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 }