epoll实现压测工具

代码:

  1 /*
  2  * g++ -o stress_test ./stress_test.cpp
  3  */
  4 
  5 #include <stdlib.h>
  6 #include <stdio.h>
  7 #include <string.h>
  8 #include <errno.h>
  9 
 10 #include <unistd.h>
 11 #include <sys/types.h>
 12 #include <sys/epoll.h>
 13 #include <fcntl.h>
 14 #include <sys/socket.h>
 15 #include <netinet/in.h>
 16 #include <arpa/inet.h>
 17 
 18 static const char *request = "GET / HTTP/1.1
Host: 192.168.1.5
Connection: keep-alive

";
 19 
 20 int setnonblocking(int fd)
 21 {
 22     int old_option = fcntl(fd, F_GETFL);
 23     int new_option = old_option | O_NONBLOCK;
 24     fcntl(fd, F_SETFL, new_option);
 25     
 26     return old_option;
 27 }
 28 
 29 int add_fd(int epoll_fd, int fd)
 30 {
 31     struct epoll_event event;
 32     event.events = EPOLLOUT | EPOLLET | EPOLLERR;
 33     event.data.fd = fd;
 34     epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event);
 35     setnonblocking(fd);
 36 }
 37 
 38 bool write_nbytes(int sockfd, const char *buffer, int len)
 39 {
 40     int bytes_write = 0;
 41     printf("write out %d bytes to socket %d
", len, sockfd);
 42     while(1)
 43     {
 44         bytes_write = send(sockfd, buffer, len, 0);
 45         if (bytes_write == -1)
 46         {
 47             printf("send failed, errno[%d], error[%s]
", errno, strerror(errno));
 48             return false;
 49         }
 50         else if (bytes_write == 0)
 51         {
 52             printf("send 0 bytes
");
 53             return false;
 54         }
 55 
 56         len -= bytes_write;
 57         buffer = buffer + bytes_write;
 58         if (len <= 0)
 59         {
 60             return true;
 61         }
 62     }
 63 }
 64 
 65 bool read_once(int sockfd, char *buffer, int len)
 66 {
 67     int bytes_read = 0;
 68     memset(buffer, '', len);
 69     bytes_read = recv(sockfd, buffer, len, 0);
 70     if (bytes_read == -1)
 71     {
 72         printf("recv failed, errno[%d], error[%s]
", errno, strerror(errno));
 73         return false;
 74     }
 75     else if (bytes_read == 0)
 76     {
 77         printf("recv 0 bytes
");
 78         return false;
 79     }
 80     printf("read in %d bytes from socket %d
", bytes_read, sockfd);
 81 
 82     return true;
 83 }
 84 
 85 int start_conn(int epoll_fd, const char *ip, int port, int num)
 86 {
 87     struct sockaddr_in addr;
 88     bzero(&addr, sizeof(addr));
 89     addr.sin_family = AF_INET;
 90     addr.sin_addr.s_addr = inet_addr(ip);
 91     addr.sin_port = htons(port);
 92 
 93     socklen_t len = sizeof(addr);
 94     for (int i = 0; i < num; ++i)
 95     {
 96         sleep(1);
 97         int fd = socket(AF_INET, SOCK_STREAM, 0);
 98         if (fd == -1)
 99         {
100             printf("socket failed, errno[%d], error[%s]
", errno, strerror(errno));
101             continue;
102         }
103 
104         if (connect(fd, (struct sockaddr*)&addr, len) == 0)
105         {
106             printf("build connection %d
", i);
107             add_fd(epoll_fd, fd);
108         }
109         else
110         {
111             printf("connect failed, errno[%d], error[%s]
", errno, strerror(errno));
112             continue;
113         }
114     }
115 }
116 
117 int close_conn(int epoll_fd, int fd)
118 {
119     epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
120 
121     printf("close socket[%d]
", fd);
122     close(fd);
123 }
124 
125 int main(int argc, char **argv)
126 {
127     if (argc != 4)
128     {
129         printf("usage:stress_test ip port num
");
130         exit(-1);
131     }
132 
133     int epoll_fd = epoll_create(10000);
134     start_conn(epoll_fd, argv[1], atoi(argv[2]), atoi(argv[3]));
135     epoll_event events[10000];
136     char buffer[2048];
137     while (1)
138     {
139         int fds = epoll_wait(epoll_fd, events, 10000, 2000);
140         for (int i = 0; i < fds; ++i)
141         {
142             int sockfd = events[i].data.fd;
143             if (events[i].events & EPOLLIN)
144             {
145                 if (!read_once(sockfd, buffer, 2048))
146                 {
147                     close_conn(epoll_fd, sockfd);
148                 }
149 
150                 struct epoll_event event;
151                 event.events = EPOLLOUT | EPOLLET | EPOLLERR;
152                 event.data.fd = sockfd;
153                 epoll_ctl(epoll_fd, EPOLL_CTL_MOD, sockfd, &event);
154             }
155             else if (events[i].events & EPOLLOUT)
156             {
157                 if (!write_nbytes(sockfd, request, strlen(request)))
158                 {
159                     close_conn(epoll_fd, sockfd);
160                 }
161 
162                 struct epoll_event event;
163                 event.events = EPOLLIN | EPOLLET | EPOLLERR;
164                 event.data.fd = sockfd;
165                 epoll_ctl(epoll_fd, EPOLL_CTL_MOD, sockfd, &event);
166             }
167             else if (events[i].events & EPOLLERR)
168             {
169                 close_conn(epoll_fd, sockfd);
170             }
171         }
172     }
173 
174     return 0;
175 }
原文地址:https://www.cnblogs.com/lit10050528/p/5808289.html