一:简介:
Webbench是一个在linux下使用的非常简单的网站压测工具。它使用fork()模拟多个客户端同时访问设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力。Webbench使用C语言编写, 代码加起来不到600行。
http://home.tiscali.cz/~cz210552/webbench.html
二:流程:
核心函数主要有main, bench, benchcore。
main函数主要就是调用getopt_long解析命令行参数,比如子进程数,子进程存活时间,使用的HTTP版本(HTTP/0.9,HTTP/1.0或HTTP/1.1),使用的HTTP方法(GET、HEAD、OPTIONS),代理等。
然后通过build_request函数生成HTTP请求报文头,最后调用bench函数处理。
在bench函数中,首先建立一个到目标host的链接,如果无法建链,则直接退出。建链成功之后直接关闭,该过程主要试探目标是否可建链。
然后调用pipe函数建立一个管道,然后创建子进程。管道主要是父进程与子进程通信,每个子进程完成自己的任务之后,都会向管道中写入任务执行情况,比如成功次数、失败次数、收到的字节数。父进程收集所有子进程的这些信息,然后做汇总聚合运算,计算出每分钟请求的页面数,每秒钟收到的字节数等。
子进程主要调用benchcore函数完成自己的任务,该函数首先设置一个定时器,超时时间为命令行参数中指明的子进程存活时间,一旦超时,则该函数返回,表明任务执行完成。
执行的任务就是:向目标建链,写入HTTP请求,根据选项决定是否读取HTTP返回。完成一次任务之后,接着执行下一次同样的任务,直到超时时间到时。
三:细节
1:switch语句
switch(method) { default: case METHOD_GET: strcpy(request,"GET");break; case METHOD_HEAD: strcpy(request,"HEAD");break; case METHOD_OPTIONS: strcpy(request,"OPTIONS");break; case METHOD_TRACE: strcpy(request,"TRACE");break; }
这种写法,主要目的应该就是增加可读性,在HTTP方法不是METHOD_HEAD、METHOD_OPTIONS以及METHOD_TRACE的情况下,都当做METHOD_GET方法处理。
2:strcspn函数
在解析URL中的host信息时用到了该函数:
strncpy(host,url+i, strcspn(url+i,"/"));
该函数是标准库的函数,包含在头文件<string.h>中,其原型如下:
size_t strcspn(const char *s1, constchar *s2);
该函数计算字符串s1中,从头开始的某子串的长度,该子串中的字符都不会在s2中出现。举例如下:
int main(intargc, char **argv) { char *s1 = argv[1]; char *s2 = argv[2]; printf("the length is%d ", strcspn(s1, s2)); }
$./1 abcdefg hij
the length is 7
$./1 defgabc hijad
the length is 0
$./1 defgabc heija
the length is 1
3:strspn函数
由strcspn函数引申,strspn的意义与其相反。它也是标准库函数,在头文件<string.h>中定义,其原型如下:
size_t strspn(const char *s1, const char*s2);
该函数计算字符串s1中,从头开始的某子串的长度,该子串中的字符都在s2中出现。举例如下:
int main(intargc, char **argv) { char *s1 = argv[1]; char *s2 = argv[2]; printf("the length is%d ", strspn(s1, s2)); }
$./1 abcde fgh
the length is 0
$./1 abcde fghaxzbhc
the length is 3
$./1 abcde edcbaheh
the length is 5
4:index函数
#include <strings.h> char * index(const char *string, int c);
该函数等价于strchr函数,返回一个指针,该指针指向字符串string中,字符c第一次出现的位置,如果字符c未出现在string中,则返回NULL,举例如下:
int main(intargc, char **argv) { char *s1 = argv[1]; int c = argv[2][0]; char *res1= index(s1, c); char *res2 = strchr(s1,c); printf("res1 is %p ",res1); printf("res2 is %p ",res2); }
$./1 abcdef h
res1 is 0x0
res2 is 0x0
$./1 abcdef a
res1 is 0x612f2d44
res2 is 0x612f2d44
$./1 abcdef c
res1 is 0x612f2d46
res2 is 0x612f2d46