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 }