epoll代码示例

  1 #include <errno.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #include <sys/types.h>
  5 #include <sys/socket.h>
  6 #include <netinet/in.h>
  7 #include <arpa/inet.h>
  8 #include <iostream>
  9 #include <sys/epoll.h>
 10 
 11 using namespace std;
 12 
 13 int main(int argc, char *argv[])
 14 {
 15     if (argc != 3)
 16     {
 17         cout << "usage: " << argv[0] << " ip port" << endl;
 18         return -1;
 19     }
 20 
 21     char *szIp = argv[1];
 22     in_addr_t iIp = inet_addr(szIp);
 23     if (iIp == INADDR_NONE)
 24     {
 25         cerr << "fail to parse ip: " << szIp << endl;
 26         return -1;
 27     }
 28     char *pEnd = NULL;
 29     uint16_t usPort = strtoul(argv[2], &pEnd, 10);
 30     if (*pEnd != '\0')
 31     {
 32         cerr << "fail to parse port: " << argv[2] << endl;
 33         return -1;
 34     }
 35 
 36     int iSockFd = socket(AF_INET, SOCK_STREAM, 0);
 37     if (iSockFd < 0)
 38     {
 39         cerr << "fail to create socket, err: " << strerror(errno) << endl;
 40         return -1;
 41     }
 42     cout << "create socket fd " << iSockFd << endl;
 43 
 44     sockaddr_in oAddr;
 45     memset(&oAddr, 0, sizeof(oAddr));
 46     oAddr.sin_family = AF_INET;
 47     oAddr.sin_addr.s_addr = iIp;
 48     oAddr.sin_port = htons(usPort);
 49     if (bind(iSockFd, (sockaddr *)&oAddr, sizeof(oAddr)) < 0)
 50     {
 51         cerr << "fail to bind addr " << szIp << ":" << usPort << ", err: " << strerror(errno) << endl;
 52         return -1;
 53     }
 54     cout << "bind addr " << szIp << ":" << usPort << endl;
 55 
 56     if (listen(iSockFd, 100) < 0)
 57     {
 58         cerr << "fail to listen on " << szIp << ":" << usPort << ", err: " << strerror(errno) << endl;
 59     }
 60     cout << "listen on socket fd " << iSockFd << endl;
 61     
 62     int iEpollFd = epoll_create(1024);
 63     if (iEpollFd < 0)
 64     {
 65         cerr << "fail to create epoll, err: " << strerror(errno) << endl;
 66         return -1;
 67     }
 68 
 69     epoll_event oEvent;
 70     oEvent.events = EPOLLIN;
 71     oEvent.data.fd = iSockFd;
 72     if (epoll_ctl(iEpollFd, EPOLL_CTL_ADD, iSockFd, &oEvent) < 0)
 73     {
 74         cerr << "fail to add listen fd to epoll, err: " << strerror(errno) << endl;
 75         return -1;
 76     }
 77 
 78     epoll_event aoEvents[1024];
 79     uint8_t acRecvBuf[1024 * 1024];
 80     while (true)
 81     {
 82         int iFdCnt = epoll_wait(iEpollFd, aoEvents, 1024, -1);
 83         if (iFdCnt < 0)
 84         {
 85             cerr << "epoll wait error, err: " << strerror(errno) << endl;
 86             return -1;
 87         }
 88 
 89         for (int i = 0; i < iFdCnt; i++)
 90         {
 91             if (aoEvents[i].data.fd == iSockFd)
 92             {
 93                 sockaddr_in oClientAddr;
 94                 socklen_t iAddrLen = sizeof(oClientAddr);
 95                 int iAcceptFd = accept(iSockFd, (sockaddr *)&oClientAddr, &iAddrLen);
 96                 if (iAcceptFd < 0)
 97                 {
 98                     cerr << "fail to accpet, err: " << strerror(errno) << endl;
 99                     continue;
100                 }
101                 cout << "recv connection from " << inet_ntoa(oClientAddr.sin_addr) << ":" << ntohs(oClientAddr.sin_port) << endl;
102 
103                 oEvent.events = EPOLLIN;
104                 oEvent.data.fd = iAcceptFd;
105                 if (epoll_ctl(iEpollFd, EPOLL_CTL_ADD, iAcceptFd, &oEvent) < 0)
106                 {
107                     close(iAcceptFd);
108                     cerr << "fail to add fd to epoll, err: " << strerror(errno) << endl;
109                     continue;
110                 }
111             }
112             else
113             {
114                 int iCurFd = aoEvents[i].data.fd;
115                 ssize_t iRecvLen = recv(iCurFd, acRecvBuf, sizeof(acRecvBuf), 0);
116                 if (iRecvLen < 0)
117                 {
118                     cerr << "fail to recv, close connection, err: " << strerror(errno) << endl;
119                     if (epoll_ctl(iEpollFd, EPOLL_CTL_DEL, iCurFd, NULL) < 0)
120                     {
121                         cerr << "fail to del fd from epoll, err: " << strerror(errno) << endl;
122                     }
123                     close(iCurFd);
124                     continue;
125                 }
126                 if (iRecvLen == 0)
127                 {
128                     cout << "connection closed by client" << endl;
129                     if (epoll_ctl(iEpollFd, EPOLL_CTL_DEL, iCurFd, NULL) < 0)
130                     {
131                         cerr << "fail to del fd from epoll, err: " << strerror(errno) << endl;
132                     }
133                     close(iCurFd);
134                     continue;
135                 }
136                 cout << "recv data len: " << iRecvLen << endl;
137 
138                 ssize_t iSendLen = send(iCurFd, acRecvBuf, iRecvLen, 0);
139                 if (iSendLen < 0)
140                 {
141                     cerr << "fail to send, err: " << strerror(errno) << endl;
142                     if (epoll_ctl(iEpollFd, EPOLL_CTL_DEL, iCurFd, NULL) < 0)
143                     {
144                         cerr << "fail to del fd from epoll, err: " << strerror(errno) << endl;
145                     }
146                     close(iCurFd);
147                     break;
148                 }
149                 cout << "echo to client, len: " << iSendLen << endl;
150             }
151         }
152     }
153 }

 

posted @ 2015-11-01 17:45  Glacier  阅读(2720)  评论(0编辑  收藏  举报