epoll_tcp.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/epoll.h>
static int startup(const char *_ip,int _port)
{
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0){
perror("socket");
exit(2);
}
struct sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(_port);
local.sin_addr.s_addr=inet_addr(_ip);
if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0){
perror("bind");
exit(3);
if(listen(sock,5)<0){
perror("listen");
exit(4);
return sock;
}
static int set_noblock(int sock)
int fl=fcntl(sock,F_GETFL);
return fcntl(sock,F_SETFL,fl|O_NONBLOCK);
static void usage(const char *proc )
printf("usage: %s [ip] [port]\n",proc);
int main(int argc,char *argv[])
if(argc!=3){
usage(argv[0]);
exit(1);
int listen_sock=startup(argv[1],atoi(argv[2])); //cteate listen socket
int epfd=epoll_create(256); // 建立一個epoll句柄,占一個fd值
if(epfd<0){
perror("epoll_create");
exit(5);
struct epoll_event _ev;
_ev.events=EPOLLIN;
_ev.data.fd=listen_sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sock, &_ev);
struct epoll_event _ready_ev[128];
int _ready_evs=128;
int _timeout=-1; //block
int nums=0;
int done=0;
while(!done){
switch( (nums=epoll_wait(epfd, _ready_ev,\
_ready_evs, _timeout)) ){
case 0:
printf("timeout...\n");
break;
case -1:
perror("epoll_wait");
default:
{
int i=0;
for(; i< nums; ++i){
int _fd=_ready_ev[i].data.fd;
if(_fd==listen_sock && \
_ready_ev[i].events & EPOLLIN){
//get a new link...
struct sockaddr_in peer;
socklen_t len=sizeof(peer);
int new_sock=accept(listen_sock,(struct sockaddr*)&peer, &len);
if(new_sock > 0){
printf("client info, socket: %s:%d\n", inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
_ev.events=EPOLLIN | EPOLLET;//ET
_ev.data.fd=new_sock;
set_noblock(new_sock);
epoll_ctl(epfd, EPOLL_CTL_ADD,\
new_sock, &_ev);
}
}else{
if(_ready_ev[i].events & EPOLLIN){
char buf[102400];
memset(buf, '\0', sizeof(buf));
//read/write
ssize_t _s=recv(_fd, buf,\
sizeof(buf)-1,0);//while need recv done...
if( _s > 0){
printf("client# %s\n",buf);
_ev.events=EPOLLOUT | EPOLLET;
_ev.data.fd=_fd;
epoll_ctl(epfd, EPOLL_CTL_MOD,\
_fd, &_ev);
}else if( _s==0 ){
printf("client close...\n");
epoll_ctl(epfd,EPOLL_CTL_DEL,\
_fd, NULL);
close(_fd);
}else{
perror("recv");
}
}else if(_ready_ev[i].events &\
EPOLLOUT){
const char *msg="HTTP/1.1 200 OK\r\n\r\n<h1>hello world =_=|| </h1>\r\n";
send(_fd, msg, strlen(msg),0);
epoll_ctl(epfd,EPOLL_CTL_DEL,_fd, NULL);
close(_fd);
}
}
}
}