webbench网站测压工具源码分析
Posted lanshanxiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webbench网站测压工具源码分析相关的知识,希望对你有一定的参考价值。
1 /* 2 * (C) Radim Kolar 1997-2004 3 * This is free software, see GNU Public License version 2 for 4 * details. 5 * 6 * Simple forking WWW Server benchmark: 7 * 8 * Usage: 9 * webbench --help 10 * 11 * Return codes: 12 * 0 - sucess 13 * 1 - benchmark failed (server is not on-line) 14 * 2 - bad param 15 * 3 - internal error, fork failed 16 * 17 */ 18 #include "socket.c" 19 #include <unistd.h> 20 #include <sys/param.h> 21 #include <rpc/types.h> 22 #include <getopt.h> 23 #include <strings.h> 24 #include <time.h> 25 #include <signal.h> 26 27 /* values */ 28 volatile int timerexpired=0;//判断测压市场是否已经达到设定的时间 29 int speed=0;//记录进程成功得到服务器相应的数量 30 int failed=0;//记录失败的数量(speed表示成功数,failed表示失败数) 31 int bytes=0;//记录进程成功读取的字节数 32 /* globals */ 33 int http10=1; /* 0 - http/0.9, 1 - http/1.0, 2 - http/1.1 *///HTTP版本 34 /* Allow: GET, HEAD, OPTIONS, TRACE */ 35 #define METHOD_GET 0 36 #define METHOD_HEAD 1 37 #define METHOD_OPTIONS 2 38 #define METHOD_TRACE 3 39 #define PROGRAM_VERSION "1.5" 40 int method=METHOD_GET;//定义HTTP请求方法:默认方式GET请求 41 int clients=1;//并发数目,默认只有一个进程发送请求,通过 -c 参数设置 42 int force=0;//是否需要等待读取从server返回的数据,0表示要等待读取 43 int force_reload=0;//是否使用缓存,1表示不缓存,0表示可以缓存页面 44 int proxyport=80;//代理服务器的端口 45 char *proxyhost=NULL;//代理服务器的端口 46 int benchtime=30;//测压时间,默认30秒,通过 -t 参数设置 47 /* internal */ 48 int mypipe[2];//使用管道进行父进程和子进程的通信 49 char host[MAXHOSTNAMELEN];//服务器端IP 50 #define REQUEST_SIZE 2048 51 char request[REQUEST_SIZE];//发送HTTP请求的内容 52 53 static const struct option long_options[]= 54 { 55 {"force",no_argument,&force,1}, 56 {"reload",no_argument,&force_reload,1}, 57 {"time",required_argument,NULL,‘t‘}, 58 {"help",no_argument,NULL,‘?‘}, 59 {"http09",no_argument,NULL,‘9‘}, 60 {"http10",no_argument,NULL,‘1‘}, 61 {"http11",no_argument,NULL,‘2‘}, 62 {"get",no_argument,&method,METHOD_GET}, 63 {"head",no_argument,&method,METHOD_HEAD}, 64 {"options",no_argument,&method,METHOD_OPTIONS}, 65 {"trace",no_argument,&method,METHOD_TRACE}, 66 {"version",no_argument,NULL,‘V‘}, 67 {"proxy",required_argument,NULL,‘p‘}, 68 {"clients",required_argument,NULL,‘c‘}, 69 {NULL,0,NULL,0} 70 }; 71 72 /* prototypes */ 73 static void benchcore(const char* host,const int port, const char *request); 74 static int bench(void); 75 static void build_request(const char *url); 76 77 /* 78 webbench在运行时可以设定压测的持续时间,以秒为单位。 79 例如我们希望测试30秒,也就意味着压测30秒后程序应该退出了。 80 webbench中使用信号(signal)来控制程序结束。 81 函数1是在到达结束时间时运行的信号处理函数。 82 它仅仅是将一个记录是否超时的变量timerexpired标记为true。 83 后面会看到,在程序的while循环中会不断检测此值, 84 只有timerexpired=1,程序才会跳出while循环并返回。 85 */ 86 static void alarm_handler(int signal) 87 { 88 timerexpired=1; 89 } 90 91 /* 92 教你如何使用webbench的函数, 93 在linux命令行调用webbench方法不对的时候运行,作为提示。 94 有一些比较常用的,比如-c来指定并发进程的多少; 95 -t指定压测的时间,以秒为单位; 96 支持HTTP0.9,HTTP1.0,HTTP1.1三个版本; 97 支持GET,HEAD,OPTIONS,TRACE四种请求方式。 98 不要忘了调用时,命令行最后还应该附上要测的服务端URL。 99 */ 100 static void usage(void) 101 { 102 fprintf(stderr, 103 "webbench [option]... URL " 104 " -f|--force Don‘t wait for reply from server. " 105 " -r|--reload Send reload request - Pragma: no-cache. " 106 " -t|--time <sec> Run benchmark for <sec> seconds. Default 30. " 107 " -p|--proxy <server:port> Use proxy server for request. " 108 " -c|--clients <n> Run <n> HTTP clients at once. Default one. " 109 " -9|--http09 Use HTTP/0.9 style requests. " 110 " -1|--http10 Use HTTP/1.0 protocol. " 111 " -2|--http11 Use HTTP/1.1 protocol. " 112 " --get Use GET request method. " 113 " --head Use HEAD request method. " 114 " --options Use OPTIONS request method. " 115 " --trace Use TRACE request method. " 116 " -?|-h|--help This information. " 117 " -V|--version Display program version. " 118 ); 119 }; 120 int main(int argc, char *argv[]) 121 { 122 int opt=0; 123 int options_index=0; 124 char *tmp=NULL; 125 126 if(argc==1) 127 { 128 usage(); 129 return 2; 130 } 131 132 while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF ) 133 { 134 switch(opt) 135 { 136 case 0 : break; 137 case ‘f‘: force=1;break; 138 case ‘r‘: force_reload=1;break; 139 case ‘9‘: http10=0;break; 140 case ‘1‘: http10=1;break; 141 case ‘2‘: http10=2;break; 142 case ‘V‘: printf(PROGRAM_VERSION" ");exit(0); 143 /** 144 *C 库函数 int atoi(const char *str) 把参数 str 所指向的字符串转换为一个整数(类型为 int 型) 145 *int atoi(const char *str) 146 *str -- 要转换为整数的字符串。 147 *该函数返回转换后的长整数,如果没有执行有效的转换,则返回零。 148 */ 149 case ‘t‘: benchtime=atoi(optarg);break; 150 case ‘p‘: 151 /* proxy server parsing server:port */ 152 /** 153 *strrchr() 函数用于查找某字符在字符串中最后一次出现的位置,其原型为: 154 *char * strrchr(const char *str, int c); 155 *【参数】str 为要查找的字符串,c 为要查找的字符。 156 *strrchr() 将会找出 str 字符串中最后一次出现的字符 c 的地址,然后将该地址返回。 157 *注意:字符串 str 的结束标志 NUL 也会被纳入检索范围,所以 str 的组后一个字符也可以被定位。 158 *【返回值】如果找到就返回该字符最后一次出现的位置,否则返回 NULL。 159 *返回的地址是字符串在内存中随机分配的地址再加上你所搜索的字符在字符串位置。设字符在字符串中首次出现的位置为 i,那么返回的地址可以理解为 str + i。 160 */ 161 /** 162 *optarg : char *optarg; //选项的参数指针 163 */ 164 tmp=strrchr(optarg,‘:‘); 165 proxyhost=optarg; 166 if(tmp==NULL) 167 { 168 break; 169 } 170 if(tmp==optarg) 171 { 172 fprintf(stderr,"Error in option --proxy %s: Missing hostname. ",optarg); 173 return 2; 174 } 175 /** 176 *C 库函数 size_t strlen(const char *str) 计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。 177 *size_t strlen(const char *str) 178 *参数:str -- 要计算长度的字符串。 179 *该函数返回字符串的长度。 180 */ 181 if(tmp==optarg+strlen(optarg)-1) 182 { 183 fprintf(stderr,"Error in option --proxy %s Port number is missing. ",optarg); 184 return 2; 185 } 186 *tmp=‘