webbench1.5源码读后总结
webbench简介
webbench由C语言写成的用于网站压力测试的一个非常简单的工具,它最多可以模拟30000个并发连接去进行测试。
webbench的安装和使用可以自行百度,也可以过下这篇文章。
webbench执行流程
命令行解析 --> 构建HTTP请求包 --> 创建指定数量的工作进程 --> 每个工作进程对测试网站在测试时间内持续发送请求/接收响应
具体分析
1. 命令行解析。
这里主要用到了getopt库。getopt库是C中常用的命令行解析库,具有如下一些常用的全局变量、结构体以及函数。
/* 常用全局变量 */ extern char* optarg; // 指向获取的option
extern int optind; // 已经解析过的option的个数
extern int opterr; // 错误码
extern int optopt;
/* 结构体:解析option时主要的结构体,用以指明有哪些指定options */
struct option {
const char* name;
int has_arg;
int* flag;
int val;
};
/* has_arg的几个宏 */
#define no_argument 0
#define require_argument 1
#define optional_argument 2
/* 常用的几个函数 */ int getopt(); int getopt_long(int __argc, char* const* __argv, const char* __shortopts, const struct option* __longopts, int* __longind); int getopt_long_only(int __argc, char* const* __argv, const char* __shortopts, const struct option* __longopts, int* __longind);
2. 构建HTTP请求包。
代码调用了build_request函数对HTTP请求包进行了构建。常见的HTTP请求包构建规则:
请求方法 URL 协议版本 \r\n
头部字段名: 值 \r\n
....
头部字段名: 值 \r\n
\r\n
\r\n
请求数据
请求方法:GET, POST, HEAD, PUT, DELETE, TRACE, CONNECT, OPTIONS
协议版本:HTTP/1.0 HTTP/1.1
头部: User-agent, Host, Pragma, Connection等等
3. 使用fork创建指定数量的工作进程,用pipe让主进程和工作进程建立通信,以便于主进程收集子进程的测试信息。
/* 使用fork创建多进程代码片段 */ static int bench(void)
{
...
for (i = ; i < clients; i++)
{
pid = fork();
if (pid <= ) // 如果是子进程或者fork失败了,退出这个循环
{
sleep();
break;
}
} ...
}
/* fork 函数声明 */ #include <unistd.h>
#include <sys/types.h> pid_t fork(void); // pid_t 在 sys/types.h 中定义 /* pipe 函数声明 */
#include <unistd.h> int pipe(int pipefd[]); /* fdopen 函数声明 */
#include <stdio.h> FILE *fdopen(int fd, const char *mode); // 打开 pipe 文件
4. 每个进程模拟一个客户端,创建socket并连接测试web,用alarm定时测试时长,在这个时间段里,客户端持续向web请求并接收响应。
这里有几点要注意:
a) 在客户端的socket需要两步完成对web的连接:创建一个socket(使用socket()函数);连接web(使用connect()函数)。
b) alarm定时时长,输入的参数只能是秒数。当定时时间到了的时候,系统会发送一个SIGALRM信号给alarm所在的进程,所以在调用alarm之前,需要注册一个信号函数sigaction或signal(代码中使用了sigaction),将SIGALRM与回调函数绑定,当系统发送SIGALRM,会调用相应的回调函数(代码中使用了alarm_handler)进行处理。
上面几个函数的声明如下
/* socket, connect 函数声明 */
#include <sys/types.h>
#include <sys/socket.h> int socket(int domain, int type, int protocol);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); /* alarm 函数声明 */
#include <unistd.h> unsigned int alarm(unsigned int seconds); /* sigaction 函数声明 */
#include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigation *oldact); struct sigaction {
void (*sa_handler) (int);
void (*sa_sigaction) (int, siginfo_t*, void*);
sigset_t sa_mask;
int sa_flag;
void (*sa_restorer) (void);
};
完!
2018-03-21 23:39:46
webbench1.5源码读后总结的更多相关文章
- Python源码读后小结
Python 笔记 前言(还是叫杂记吧) 在python中一切皆对象, python中的对象体系大致包含了"类型对象", "Mapping对象(dict)", ...
- PHP源码安装后设置别名
PHP源码安装后测试是否能正常运行 每次在php目录./bin./php调用php很不方便,可以设置别名(方法一) vi ~/.bash_profile (修改根目录下这个文件) 设置完成后还 ...
- 复用微信小程序源码包后仍然有原小程序的版本管理怎么处理
前言: 复用微信小程序源码包后,重新创建项目导入源码包,会发现开发者工具版本管理中仍然有原来小程序的版本,这样就不太好了.毕竟是一个新的小程序,需要有新的版本控制的.那么这个问题怎么处理呢? 解决方案 ...
- vue打包时,assets目录 和static目录下文件的处理区别(nodeModule中插件源码修改后,打包后的文件应放在static目录)
为了回答这个问题,我们首先需要了解Webpack如何处理静态资产.在 *.vue 组件中,所有模板和CSS都会被 vue-html-loader 及 css-loader 解析,并查找资源URL.例如 ...
- Andriod下载源码导入后AndroidManifest.xml小红叉的解决办法
问题描述: 下载源码后,用eclipse导入,AndroidManifest.xml小红叉,而且AndroidManifest.xml打不开无法编译,请高人指点! 解决办法: 网上下载的工程文件夹不要 ...
- OpenERP 源码变更后数据库升级
转自:http://vivianyw.blog.163.com/blog/static/13454742220142114422130/?latestBlog OpenERP代码升级后需要对数据进行升 ...
- openfire源码修改后如何打包部署到linux服务器上
原文:http://blog.csdn.net/jinzhencs/article/details/50457152 1.linux版本的3.10.3解压部署启动(过程略,参考我的另一篇博文http: ...
- openfire源码编译后部署到linux
1.源码通过编号后,会生成target目录,直接把target目录拷贝到linux下即可: 2.启动openfire: ./openfire.sh start 3.退出直接ctr + c 问题:如果一 ...
- bilibili源码泄漏后,程序员们从代码里扒出来的彩蛋
昨天bilibili又上热搜了,被某人在github上开了个账号,传了份整个后端代码到github,这是被人扒光了衣服看个精光啊. 这件事情,作为程序员的我们除了调侃和fork的同时,想一想,造成这个 ...
随机推荐
- 关于vc++ 6.0 编译器,点打开文件时自动关闭
装好VC++ 6.0后,点打开文件时编译器会自动关闭掉,然后在网上找到各位大神写的资料,果然是因为之前有安装vs2010冲突的缘故,然后http://download.csdn.net/source/ ...
- 数据库-mysql事务
MySQL 事务 MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数 ...
- Codeforces 225C Barcode(矩阵上DP)
题目链接:http://codeforces.com/contest/225/problem/C 题目大意: 给出一个矩阵,只有两种字符'.'和'#',问最少修改多少个点才能让每一列的字符一致,且字符 ...
- 删除数据库所有存储过程的SQL语句
--/第1步**********删除所有表的外键约束*************************/ DECLARE c1 cursor for select 'alter table ['+ o ...
- Linux学习笔记:wc查看文件字节数、字数、行数
Linux系统中的wc(Word Count)命令可以统计指定文件中的字节数.字数.行数,并将统计结果显示输出. 若不指定文件名称,或是所给予的文件名为“-”,则wc指令会从标准输入设备读取数据. 语 ...
- MySQL学习笔记:set autocommit=0和start transaction
在MySQL中,接触事务的例子比较少,今晚在一个简单的存储过程中,循环插入50000条id数据的时候,得知必须开事务,如果逐提交数据,将会导致速度异常的慢. SET autocommit = 0; ...
- js对象的属性:数据(data)属性和访问器(accessor)属性
此文为转载,原文: 深入理解对象的数据属性与访问器属性 创建对象的方式有两种:第一种,通过new操作符后面跟Object构造函数,第二种,对象字面量方式.如下 var person = new Obj ...
- entityframework导航属性筛选
); //会在sql代码中生成Street = "上海"代码 var address1 = db.Entry(user).Collection(b => b.Address) ...
- day6作业--游戏人生
本节作业: 熟练使用类和模块,写一个交互性强.有冲突的程序. 思路: 1.各个模块之间的调用关系,如何使用类,各种方法的使用上面: 2.学了类,以为能用来解决所有问题,东西都要写在类里面: 3.下面自 ...
- 【LOJ】#2040. 「SHOI2015」零件组装机
题解 我写的应该有bug但是我懒得改了 就是最后一次合并的n要么是0点边集的最后一条边,要么是0点边集最后两条边的差,我们分别拎出来判断一下哪个可行(也许两个都可行,但是我不想多做修改了--) 然后递 ...