后续知识会进行整理
代码
#ifdef ____Win32
#else
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include #define SERVERPORT 3119int main() {int listenfd &#61; socket(AF_INET, SOCK_STREAM, 0);if (listenfd &#61;&#61; -1) {printf("socket error \n");return -1;}int on &#61; 1;setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof(on));int oldSocketFlag &#61; fcntl(listenfd, F_GETFL, 0);int newSocketFlag &#61; oldSocketFlag | O_NONBLOCK;if (fcntl(listenfd, F_SETFL, newSocketFlag) &#61;&#61; -1) {close(listenfd);printf("fcntl error \n");return -1;}struct sockaddr_in bindaddr;bindaddr.sin_family &#61; AF_INET;bindaddr.sin_addr.s_addr &#61; htonl(INADDR_ANY);bindaddr.sin_port &#61; htons(SERVERPORT);if (bind(listenfd, (struct sockaddr *) &bindaddr, sizeof(bindaddr)) &#61;&#61; -1) {printf("bind error \n");close(listenfd);return -1;} if (listen(listenfd, SOMAXCONN) &#61;&#61; -1) {printf("listen error \n");close(listenfd);return -1; }int epollfd &#61; epoll_create(1);if (epollfd &#61;&#61; -1) {printf("epoll_create error \n");close(listenfd);return -1; }struct epoll_event listen_fd_event;listen_fd_event.data.fd &#61; listenfd;listen_fd_event.events &#61; EPOLLIN; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &listen_fd_event) &#61;&#61; -1) {printf("epoll_ctl error \n");close(listenfd);return -1; }int n;while(1) {struct epoll_event epoll_events[1024];n &#61; epoll_wait(epollfd, epoll_events, 1024, 1000);if (n < 0) {if (errno &#61;&#61; EINTR) continue;break;}else if (n &#61;&#61; 0) {continue;}for (size_t i &#61; 0; i < n; &#43;&#43; i) {if (epoll_events[i].events & EPOLLIN) {if (epoll_events[i].data.fd &#61;&#61; listenfd) {printf("a new client is connect! \n");struct sockaddr_in clientaddr;socklen_t clientaddrlen &#61; sizeof(clientaddr);int clientfd &#61; accept(listenfd, (struct sockaddr *) &clientaddr, &clientaddrlen);if (clientfd !&#61; -1) {int oldSocketFlag &#61; fcntl(clientfd, F_GETFL, 0);int newSocketFlag &#61; oldSocketFlag | O_NONBLOCK;if (fcntl(clientfd, F_SETFL, newSocketFlag) &#61;&#61; -1) {close(clientfd);printf("set client to nonblocking error \n");}else {struct epoll_event client_fd_event;client_fd_event.data.fd &#61; clientfd;client_fd_event.events &#61; EPOLLIN | EPOLLOUT; client_fd_event.events |&#61; EPOLLET;if (epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &client_fd_event) !&#61; -1) {}else {printf("add client fd to epollfd error \n");close(clientfd);}}}}else {printf("client fd: %d recv data \n", epoll_events[i].data.fd);char recvbuf[1024] &#61; { 0 };int m &#61; recv(epoll_events[i].data.fd, &recvbuf, 1024, 0);if (m &#61;&#61; 0) {if (epoll_ctl(epollfd, EPOLL_CTL_DEL, epoll_events[i].data.fd, NULL) !&#61; -1) {printf("client disconnected clientfd: %d \n", epoll_events[i].data.fd);}close(epoll_events[i].data.fd);}else if (m < 0) {if (errno !&#61; EWOULDBLOCK && errno !&#61; EINTR) {if (epoll_ctl(epollfd, EPOLL_CTL_DEL, epoll_events[i].data.fd, NULL) !&#61; -1) {printf("client disconnected clientfd: %d \n", epoll_events[i].data.fd);}close(epoll_events[i].data.fd);}}else {printf("recv from client: %d,%s", epoll_events[i].data.fd, recvbuf);struct epoll_event client_fd_event;client_fd_event.data.fd &#61; epoll_events[i].data.fd;client_fd_event.events &#61; EPOLLIN | EPOLLOUT | EPOLLET;if (epoll_ctl(epollfd, EPOLL_CTL_MOD, epoll_events[i].data.fd, &client_fd_event) !&#61; -1) {}else {printf("epoll_ctl failure, mode: EPOLL_CTL_MOD, clientfd: %d \n", epoll_events[i].data.fd);}}}}else if (epoll_events[i].events & EPOLLOUT) {if (epoll_events[i].data.fd !&#61; listenfd) {}}else if (epoll_events[i].events & EPOLLERR) {printf("epoll error! \n");}}} close(listenfd);return 0;
}
#endif
测试
> gcc -g -o epoll_server epoll_server.c
> ./epoll_server
a new client is connect!
client fd: 5 recv data
recv from client: 5,asdh
client fd: 5 recv data
recv from client: 5,awqr
> nc -v 127.0.0.1 3119
Connection to 127.0.0.1 3119 port [tcp/*] succeeded!
asdh
awqr