本段代码摘自《Linux高性能服务器编程》第16.4章节
压力测试程序有很多种实现方式,比如I/O复用方式,多线程、多进程并发编程方式,以及这些方式的结合使用。不过,单纯的I/O复用方式的施压程度是最高的,因为线程和进程的调度本身也是要占用一定CPU时间的。因此,我们将使用epoll来实现一个通用的服务器压力测试程序,如代码清单16-4所示。

#include <stdlib.h> #include <stdio.h> #include <assert.h> #include <unistd.h> #include <sys/types.h> #include <sys/epoll.h> #include <fcntl.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> static const char* request = "GET http://localhost/index.html HTTP/1.1 Connection: keep-alive xxxxxxxxxxxx"; int setnonblocking( int fd ) { int old_option = fcntl( fd, F_GETFL ); int new_option = old_option | O_NONBLOCK; fcntl( fd, F_SETFL, new_option ); return old_option; } void addfd( int epoll_fd, int fd ) { epoll_event event; event.data.fd = fd; event.events = EPOLLOUT | EPOLLET | EPOLLERR; epoll_ctl( epoll_fd, EPOLL_CTL_ADD, fd, &event ); setnonblocking( fd ); } bool write_nbytes( int sockfd, const char* buffer, int len ) { int bytes_write = 0; printf( "write out %d bytes to socket %d ", len, sockfd ); while( 1 ) { bytes_write = send( sockfd, buffer, len, 0 ); if ( bytes_write == -1 ) { return false; } else if ( bytes_write == 0 ) { return false; } len -= bytes_write; buffer = buffer + bytes_write; if ( len <= 0 ) { return true; } } } bool read_once( int sockfd, char* buffer, int len ) { int bytes_read = 0; memset( buffer, '