1 #include <stdio.h>
2 #include <string.h>
3 #include <errno.h>
4
5 #include <iostream>
6
7 #include <sys/socket.h>
8 #include <netdb.h>
9 #include <arpa/inet.h>
10
11 #include <fcntl.h>
12 #include <unistd.h>
13
14 #include <sys/epoll.h>
15
16 #define MAX_EVENTS 1024
17
18 using namespace std;
19
20 static int setSocketNonBlock(const int socketFd)
21 {
22 int ret(0);
23
24 int flags = fcntl(socketFd, F_GETFL, 0);
25 if (-1 == flags)
26 {
27 cerr << "fcntl error" << endl;
28 return -1;
29 }
30
31 flags |= O_NONBLOCK;
32 ret = fcntl(socketFd, F_SETFL, flags);
33 if (-1 == ret)
34 {
35 cerr << "fcntl error" << endl;
36 return -1;
37 }
38
39 return 0;
40 }
41
42 static int setSocketLingerDisable(const int socketFd)
43 {
44 int ret(0);
45
46 struct linger lingerVal;
47 lingerVal.l_onoff = 1;
48 lingerVal.l_linger = 0;
49 ret = setsockopt(socketFd, SOL_SOCKET, SO_LINGER, &lingerVal, sizeof(struct linger));
50 if (0 != ret)
51 {
52 cerr << "setsockopt" << endl;
53 return -1;
54 }
55
56 return 0;
57 }
58
59 static int create_and_bind()
60 {
61 int ret(0);
62
63 struct addrinfo hints;
64 struct addrinfo * retAddr, * retNext;
65
66 memset(&hints, 0, sizeof(struct addrinfo));
67 hints.ai_family = AF_UNSPEC;
68 hints.ai_socktype = SOCK_STREAM;
69 hints.ai_protocol = IPPROTO_TCP;
70 hints.ai_flags = AI_PASSIVE;
71 ret = getaddrinfo(NULL, "8090", &hints, &retAddr);
72 if (0 != ret)
73 {
74 cerr << "getaddrinfo" << endl;
75 return -1;
76 }
77
78 int listenSocket(-1);
79
80 for (retNext = retAddr; retNext != NULL; retNext = retNext->ai_next)
81 {
82 // char ipBuf[1024];
83 // switch(retNext->ai_family)
84 // {
85 // case AF_INET:
86 // inet_ntop(AF_INET, &((struct sockaddr_in *)(retNext->ai_addr))->sin_addr, ipBuf, sizeof(char[1024]));
87 // break;
88 // case AF_INET6:
89 // inet_ntop(AF_INET6, &((struct sockaddr_in6 *)(retNext->ai_addr))->sin6_addr, ipBuf, sizeof(char[1024]));
90 // break;
91 // }
92 // cout << "ipBuf: " << ipBuf << endl;
93
94 listenSocket = socket(retNext->ai_family, retNext->ai_socktype, retNext->ai_protocol);
95 if (-1 == listenSocket)
96 {
97 cerr << "socket error" << endl;
98 continue;
99 }
100
101 ret = bind(listenSocket, retNext->ai_addr, retNext->ai_addrlen);
102 if (0 != ret)
103 {
104 cerr << " bind error" << endl;
105 close(listenSocket);
106 continue;
107 }
108
109 break; // 已成功生成并绑定监听socket, 退出for遍历
110 }
111
112 freeaddrinfo(retAddr);
113
114 if (NULL == retNext)
115 {
116 cerr << "create_and_bind error" << endl;
117 return 1;
118 }
119
120 return listenSocket;
121 }
122
123 int main(int argc, char **argv)
124 {
125 int ret(0);
126
127 int listenSocket(-1);
128 listenSocket = create_and_bind();
129 if (-1 == listenSocket)
130 {
131 return -1;
132 }
133
134 ret = setSocketNonBlock(listenSocket);
135 if (0 != ret)
136 {
137 return -1;
138 }
139
140 ret = setSocketLingerDisable(listenSocket);
141 if (0 != ret)
142 {
143 return -1;
144 }
145
146 ret = listen(listenSocket, 10);
147 if (0 != ret)
148 {
149 cerr << "listen error" << endl;
150 return -1;
151 }
152
153 int epollFd(-1);
154 epollFd = epoll_create1(0);
155 if (-1 == epollFd)
156 {
157 cerr << "epoll_create1 error" << endl;
158 return -1;
159 }
160
161 // 监听socket注册到epollFd中管理
162 struct epoll_event event;
163 event.data.fd = listenSocket;
164 event.events = EPOLLET | EPOLLIN;
165 ret = epoll_ctl(epollFd, EPOLL_CTL_ADD, listenSocket, &event);
166 if (0 != ret)
167 {
168 cerr << "epoll_ctl error" << endl;
169 return -1;
170 }
171
172 struct epoll_event retEvents[MAX_EVENTS];
173
174 bool done(false);
175 int retEventsCnt(0);
176 while (!done)
177 {
178 retEventsCnt = epoll_wait(epollFd, retEvents, MAX_EVENTS, 1000);
179 cout << "retEventCnt: " << retEventsCnt << endl;
180 for (int i = 0; i < retEventsCnt; ++i)
181 {
182 if ((retEvents[i].events & EPOLLERR) || (retEvents[i].events & EPOLLHUP) ||
183 !(retEvents[i].events & EPOLLIN))
184 {
185 cerr << "socketFd: " << retEvents[i].data.fd << " error" << endl;
186 close(retEvents[i].data.fd);
187 continue;
188 }
189 else if (listenSocket == retEvents[i].data.fd)
190 {
191 while (true)
192 {
193 struct sockaddr remoteSockAddr;
194 socklen_t len = sizeof(struct sockaddr);
195
196 int connectSocket(-1);
197 connectSocket = accept(listenSocket, &remoteSockAddr, &len);
198 if (-1 == connectSocket)
199 {
200 if (EAGAIN == errno)
201 {
202 break;
203 }
204 else
205 {
206 cerr << "accept error" << endl;
207 continue;
208 }
209 }
210
211 char hostStr[100];
212 char serviceStr[100];
213 ret = getnameinfo(&remoteSockAddr, sizeof(struct sockaddr), hostStr, sizeof(char[100]),
214 serviceStr, sizeof(char[100]), 0);
215 if (0 == ret)
216 {
217 printf("client info: [connectSocket: %d, host: %s, port: %s]\n", connectSocket, hostStr, serviceStr);
218 }
219
220 ret = setSocketNonBlock(connectSocket);
221 if (0 != ret)
222 {
223 return -1;
224 }
225
226 ret = setSocketLingerDisable(connectSocket);
227 if (0 != ret)
228 {
229 return -1;
230 }
231
232 event.data.fd = connectSocket;
233 event.events = EPOLLET | EPOLLIN;
234
235 ret = epoll_ctl(epollFd, EPOLL_CTL_ADD, connectSocket, &event);
236 if (0 != ret)
237 {
238 cerr << "epoll_ctl error" << endl;
239 return -1;
240 }
241 }
242 }
243 else
244 {
245 bool closeFlag(false);
246
247 while (true)
248 {
249 char recvBuf[10];
250
251 int len(-1);
252 len = recv(retEvents[i].data.fd, recvBuf, sizeof(char[10]), 0);
253 if (-1 == len)
254 {
255 if (EAGAIN == errno) // 读完了
256 {
257 break;
258 }
259 closeFlag = true;
260 }
261 else if (0 == len)
262 {
263 closeFlag = true;
264 break;
265 }
266
267 write(1, recvBuf, len);
268 }
269
270 if(closeFlag)
271 {
272 cout << "close connectSocket Fd: " << retEvents[i].data.fd << endl;
273 close(retEvents[i].data.fd);
274 }
275 }
276 }
277 }
278
279 close(listenSocket);
280
281 return 0;
282 }