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源码读后总结的更多相关文章

  1. Python源码读后小结

    Python 笔记 前言(还是叫杂记吧) 在python中一切皆对象, python中的对象体系大致包含了"类型对象", "Mapping对象(dict)", ...

  2. PHP源码安装后设置别名

    PHP源码安装后测试是否能正常运行 每次在php目录./bin./php调用php很不方便,可以设置别名(方法一) vi ~/.bash_profile     (修改根目录下这个文件) 设置完成后还 ...

  3. 复用微信小程序源码包后仍然有原小程序的版本管理怎么处理

    前言: 复用微信小程序源码包后,重新创建项目导入源码包,会发现开发者工具版本管理中仍然有原来小程序的版本,这样就不太好了.毕竟是一个新的小程序,需要有新的版本控制的.那么这个问题怎么处理呢? 解决方案 ...

  4. vue打包时,assets目录 和static目录下文件的处理区别(nodeModule中插件源码修改后,打包后的文件应放在static目录)

    为了回答这个问题,我们首先需要了解Webpack如何处理静态资产.在 *.vue 组件中,所有模板和CSS都会被 vue-html-loader 及 css-loader 解析,并查找资源URL.例如 ...

  5. Andriod下载源码导入后AndroidManifest.xml小红叉的解决办法

    问题描述: 下载源码后,用eclipse导入,AndroidManifest.xml小红叉,而且AndroidManifest.xml打不开无法编译,请高人指点! 解决办法: 网上下载的工程文件夹不要 ...

  6. OpenERP 源码变更后数据库升级

    转自:http://vivianyw.blog.163.com/blog/static/13454742220142114422130/?latestBlog OpenERP代码升级后需要对数据进行升 ...

  7. openfire源码修改后如何打包部署到linux服务器上

    原文:http://blog.csdn.net/jinzhencs/article/details/50457152 1.linux版本的3.10.3解压部署启动(过程略,参考我的另一篇博文http: ...

  8. openfire源码编译后部署到linux

    1.源码通过编号后,会生成target目录,直接把target目录拷贝到linux下即可: 2.启动openfire: ./openfire.sh start 3.退出直接ctr + c 问题:如果一 ...

  9. bilibili源码泄漏后,程序员们从代码里扒出来的彩蛋

    昨天bilibili又上热搜了,被某人在github上开了个账号,传了份整个后端代码到github,这是被人扒光了衣服看个精光啊. 这件事情,作为程序员的我们除了调侃和fork的同时,想一想,造成这个 ...

随机推荐

  1. 使用html+css+js实现日历与定时器,看看今天的日期和今天剩余的时间。

    使用html+css+js实现日历与定时器,看看今天的日期和今天剩余的时间. 效果图: 哎,今天就又这么过去了,过的可真快 . 代码如下,复制即可使用: <!DOCTYPE html> & ...

  2. 向SQL Server 现有表中添加新列并添加描述.

    注: sql server 2005 及以上支持. 版本估计是不支持(工作环境2005,2008). 工作需要, 需要向SQL Server 现有表中添加新列并添加描述. 从而有个如下存储过程. (先 ...

  3. T-SQL创建前删除已存在存储过程

    --判断是否存在addOneArticle这个存储过程 if Exists(select name from sysobjects where NAME = 'addOneArticle' and t ...

  4. gif处理

    UleadGIFAnimator-v5.05破解版 网盘地址:https://pan.baidu.com/s/1bpf6iVP 2017-02-19  10:39:58

  5. Android 客户端 okhttp3 与服务器之间的双向验证

    [原文]https://blog.csdn.net/leng_wen_rou/article/details/58596142 本篇是Android 客户端基于okhttp3的网络框架 和后台服务器之 ...

  6. ThinkPHP导入第三方类库Vendor

    详情查看ThinkPHP3.2手册 架构 > 自动加载 章节 vendor('Uploader','','.class.php')

  7. js获取单个查询串的值

    function getSearchString(key) { // 获取URL中?之后的字符 var searchArr= window.location.href.split('#')[0].sp ...

  8. Java 集合之 Map

    Map 就是另一个顶级接口了,总感觉 Map 是 Collection 的子接口呢.Map 主要用于表示那些含有映射关系的数据,存储的是一组一组的键值对.Map 是允许你将某些对象与其它一些对象关联起 ...

  9. web服务端安全之文件上传漏洞

    一.文件上传漏洞的原理 由于程序代码未对用户提交的文件进行严格的分析和检查,导致攻击者可以上传可执行的代码文件,从而获取web应用的控制权限. 常见于上传功能,富文本编辑器. 二.文件上传漏洞的防御 ...

  10. Javascript中call方法和apply方法用法和区别

    第一次在博客园上面写博客,知识因为看书的时候发现了一些有意思的知识,顺便查了一下资料,就发到博客上来了,希望对大家有点帮助. 连续几天阅读<javascript高级程序设计>这本书了,逐渐 ...