#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); 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"); Break 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, ' n ', 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 Ok\r\n\r\nSend (_FD, MSG, strlen (msg), 0); Epoll_ctl (EPFD,EPOLL_CTL_DEL,_FD, NULL); Close (_FD); } } } } Break } } } |