webbench源码学习-->命令行选项解析函数getopt和getopt_long函数
对于webbench这个网站压力测试工具网上介绍的很多,有深度详解剖析的,对于背景就不在提了,
听说最多可以模拟3万个并发连接去测试网站的负载能力,这里主要是学习了一下它的源码,做点
笔记。
官方介绍:
Web Bench is very simple tool for benchmarking WWW or proxy servers. Uses fork() for simulating
multiple clientsand can use HTTP/0.9-HTTP/1.1 requests. This benchmark is not very realistic, but
it can test if your HTTPD can realy handle that many clients at once (try to run some CGIs) without
taking your machine down. Displays pages/min and bytes/sec. Can be used in more aggressive
mode with -f switch.
安装使用:
安装和使用也很简单,在官网:http://home.tiscali.cz/~cz210552/下载最新的包,安装即可:
1. 解压
# 命令: tar xf webbench-1.5.tar.gz
# cd webbench
2. 安装
# 命令: make && make install
3. 使用

webbench -c 100[并发数] -t 60[运行测试时间] URL[注意:URL必须以/ 结尾否则提示不合法的URL]

测试结果解读
当并发是100时:
向google并发100个请求,持续时间60s,我们看到速度:每分钟相应请求数Speed = 6652 pages/min,
每秒钟传输数据量59427字节。返回6652次请求成功,0次失败。
正文:
如标题主要学习记录一下命令行参数解析函数getopt和getopt_long的使用,开工~~
函数原型
#include<unistd.h>
#include<getopt.h> //所在头文件 int getopt(int argc, char * const argv[], const char *optstring);
int getopt_long(int argc, char * const argv[], const char *optstring,
const struct option *longopts, int*longindex);
int getopt_long_only(int argc, char * const argv[],const char *optstring,
const struct option *longopts, int*longindex); extern char *optarg; //系统声明的全局变量
extern int optind, opterr, optopt;
参数解释
argc: main()函数传递进来的参数个数
argv: main()函数传递过来的参数的字符串指针数组
optstring: 选项字符串,告知getopt()可以处理那个选项以及那个选项需要参数 optarg -> 指向当前选项参数(如果有)的指针
optind -> 再次调用getopt()时的下一个argv指针的索引
optopt -> 最后一个未知选项
opterr -> 如果不希望getopt()打印出错误信息,则只要将全局变量opterr设为0即可 char *optstring = "ab:c::"; // 实例
// 单个字符a 表示选项a没有参数 格式:-a 即可,不加参数
// 单个字符加冒号b: 表示选项b有且必须加参数, 格式: -b 100或-b100,但-b=100错误
// 单个字符加2冒号c:: 表示选项c可以有,也可以无, 格式: -c200,其他格式错误
Demo 1
getopt.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h> // 使用包含的头文件 int main(int argc, char *argv[])
{
int opt;
char *string = "a::b:c:d";
/*
a::b:c:d
a:: 表示a可以有参数可以无, 格式 -a200
b: 表示有且必须加参数, 格式 -b 100,或-b100
d 单个字符,没有参数 */ while((opt = getopt(argc, argv, string)) != -){
printf("opt = %c\t\t", opt);
printf("optarg = %s\t\t", optarg);
printf("optind = %d\t\t", optind);
printf("argv[optind] = %s\n", argv[optind]);
} return ;
}
编译运行:gcc getopt -o getopt
./getopt -a200 -b 100 -c100 -d

Demo 2
getopt_long.c
/*
在Unix/Linux的正式项目上,通过使用getopt()或者getopt_long()来
获取输入的参数,两者的一个区别在于getopt()只支持段格式参数,而
getopt_long()即支持短格式参数,又支持长格式参数。 短格式: ./destory -f cdr -o cdr.txt -c cdr.desc -k 1234
长格式: ./destory --file cdr --output cdr.txt --config cdr.desc --keyword 1233 函数原型: int getopt_long(int argc, char *const argv[],
const char *optstring,
const struct option *longopts, int *longindex); 在这里,longopts指向一个有option结构体组成的数组,那个数组的每个元素,指明了一个
"长参数"(即形如--name的参数)名称和性质: struct option {
const char *name;
int has_arg;
int *flg;
int val;
};
name 是参数的名称 has_arg 指明是否带参数值,其数值可选:
no_argument (0) 表明这个长参数不带参数(即不带数值,如: --name)
required_argument (1) 表明这个长参数必须带参数(如: --name zzhao)
optional_argument (2) 表明这个长参数后面带的参数时可选的,可有可无 flag 当这个指针为空的时候,函数直接将val的数值从getopt_long的返回值返回出去
当它非空是,val的值会被赋到flag指向的整形数中,而函数返回值为0 val 用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值 longindex 如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述
即是longopts的下标值。
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h> /*usage 信息*/
static void print_usage(const char *program_name)
{
printf("%s 1.0.0 (2018-0524)\n",program_name);
printf("This is a program decoding a BER endocded CDR file\n");
printf("Usage: %s -f <file_name> -o <output_name> [-c <config_name>] [-k <keyword>]\n",program_name);
printf(" -f --file the CDR file to be decoded\n");
printf(" -o --output the output file in plain text format\n");
printf(" -c --config the description file of the CDR file, if not given, use default configuration\n");
printf(" -k --keyword the keyword to search,if not given, all records will be written into output file\n"); }
/*Usage 信息-> 这种在实际项目中多见,功能同上面的 print_usage*/
static void usage(void)
{
fprintf(stderr,
"Usage: -f <file_name> -o <output_name> [-c <config_name>] [-k <keyword>]\n"
" -f|--file the CDR file to be decoded.\n"
" -o|--output the output file in plain text format.\n"
" -c|--config the description file of the CDR file, if not given ,use default configuration.\n"
" -k|--keyword the keyword to search ,if not given ,all records will be written into output file.\n"
);
} /* 结构体数组,定义long_opts*/
const struct option long_opts[] = {
{"help", no_argument, NULL, 'h'},
{"file", required_argument, NULL, 'f'},
{"output", required_argument, NULL, 'o'},
{"config", required_argument, NULL, 'c'},
{"keyword", required_argument, NULL, 'k'},
{NULL, , NULL, }
};
// main 函数
int main(int argc, char *argv[])
{
char *file_name = NULL;
char *output_name = NULL;
char *config_name = NULL;
char *keyword = NULL;
// 短参数
const char *short_opt = "hf:o:c:k:";
int hflag = ;
int opt = ;
int options_index = ;
opterr = ; if(argc == ){
usage();
return ;
} while((opt = getopt_long(argc,argv,short_opt,long_opts,&options_index)) != -) {
switch(opt)
{
case 'h':
hflag = ;break;
case 'f':
file_name = optarg;break;
case 'o':
output_name = optarg;break;
case 'c':
config_name = optarg;break;
case 'k':
keyword = optarg;break;
case '?':
if(optarg == (char *)'f' || optarg == (char *)'o' || optarg == (char *)'c' || optarg == (char *)'k')
printf("Error: option -%c requires an argument\n", optarg);
else if(isprint(optarg))
printf("Error: unknown option '-%c\n'",optarg);
else
printf("Error: unknown option character '//x%x'\n", optarg);
return ;
default:
abort();
}
}
/* if(hflag || argc == 1)
{
print_usage(argv[0]); // 打印Usage信息
return 0;
}*/
if(!file_name){
printf("Error: file name must be specified\n");
return ;
}
if(!output_name){
printf("Error: output name must be specified\n");
return ;
}
// if not setting default, linux OK, but SunOS core dump
if(!config_name) config_name = "(null)";
if(!keyword) keyword = "(null)";
// 打印输入的参数
printf("Parameters got: file_name = %s, output_name = %s, config_name = %s, keyword = %s\n",
file_name,output_name,config_name,keyword); return ;
}
编译运行

后记:
奈何、奈何
冷冬悲苦心怅惘,强颜欢笑几人懂
我愿长醉不复醒,此恨缠绵无绝期
幽幽地冥十二刹,牛马铁索心上寒
惶惶炼狱十八层, 阎罗判官不作解
奈何桥畔花落去,痴情不饮孟婆汤
今生无缘比翼飞,来世连理在枝头
可笑命运太无常,不胜梦中一场醉
伊人一笑解千愁,弹指一挥岁月老
花开叶落终有期,心碎这般若止水
人间对错本无界,何不把酒话桑麻
问君此生何所憾,淡然一笑把话藏
瑶琴一把指上弹,愿卿为我座上听
年少白衣曾不羁,情为何物惹乡愁
无端由来一场梦,为你走马到天涯
世间万物不足提,唯愿与卿到白首
前路荆棘何所惧,彼岸花香待芳华
我耕你织笑无言,默然相守无所求
闲来无事画碧楼,玉阶微凉夜雪飞
一壶浊酒醉明月,与卿笑谈天下事
风扶雪花翩翩舞,月光星华照无眠
此景只应梦中有,何期与共今宵逢
执子之手私语时,满地黄花不抬头
多情总被无情恼,相逢何必曾相识
待到如梦初醒时,不得落笔已成殇
飘飘兮
如流风之回雪
寥寥兮
似长空之燕不归
呜呼
哀哉
奈何、奈何

webbench源码学习-->命令行选项解析函数getopt和getopt_long函数的更多相关文章
- 命令行选项解析函数getopt()
1.定义: int getopt(int argc, char * const argv[], const char *optstring); 2.描述: getopt是用来解析命令行选项参数的,但是 ...
- 命令行参数解析函数getopt和getopt_long函数【转】
原文地址:http://blog.csdn.net/cashey1991/article/details/7942809 getopt和getopt_long函数 平时在写程序时常常需要对命令行参 ...
- 命令行选项解析函数(C语言):getopt()和getopt_long()
命令行选项解析函数(C语言):getopt()和getopt_long() 上午在看源码项目webbench时,刚开始就被一个似乎挺陌生函数getopt_long()给卡住了,说实话这函数没怎么见过, ...
- Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类
Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何 ...
- webbench源码学习笔记
学习内容 一共五百多行代码,其中包含了linux编程常用的API.可以通过学习源码,把不熟悉的API练习练习. 1 如何使用webbench (1)查看参数帮助 (2)运行方法 即以上模拟30个客户端 ...
- jquery 源码学习(四)构造jQuery对象-工具函数
jQuery源码分析-03构造jQuery对象-工具函数,需要的朋友可以参考下. 作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原 ...
- 【js】vue 2.5.1 源码学习 (十一) 模板编译compileToFunctions渲染函数
大体思路(九) 本节内容: 1. compileToFunctions定位 1. compileToFunctions定位 ==> createCompiler = createCompiler ...
- Underscore.js 源码学习笔记(下)
上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...
- Hadoop源码学习笔记(6)——从ls命令一路解剖
Hadoop源码学习笔记(6) ——从ls命令一路解剖 Hadoop几个模块的程序我们大致有了点了解,现在我们得细看一下这个程序是如何处理命令的. 我们就从原头开始,然后一步步追查. 我们先选中ls命 ...
随机推荐
- 回顾:C++开篇课堂
周三,在刚刚结束矩阵分析的考试之后,面向对象程序设计课正式开始了C++的学习,这次课的重点即是面向对象思想的理解. 梳理一下知识点. C++中函数的默认参数 在函数声明或者在函数定义时,对参数赋初始值 ...
- UVa 1001 奶酪里的老鼠(Dijkstra或Floyd)
https://vjudge.net/problem/UVA-1001 题意:一个奶酪里有n个洞,老鼠在奶酪里的移动速度为10秒一个单位,但是在洞里可以瞬间移动.计算出老鼠从A点到达O点所需的最短时间 ...
- UVa 10881 蚂蚁
https://vjudge.net/problem/UVA-10881 题意: 一根长度为L厘米的木棍上有n只蚂蚁,每只蚂蚁要么朝左爬,要么朝右爬,速度为1厘米/秒.当两只蚂蚁相撞时,二者同时掉头. ...
- POJ 2965 The Pilots Brothers' refrigerator (枚举+BFS+位压缩运算)
http://poj.org/problem?id=2965 题意: 一个4*4的矩形,有'+'和'-'两种符号,每次可以转换一个坐标的符号,同时该列和该行上的其他符号也要随之改变.最少需要几次才能全 ...
- List<T>随机返回一个
/// <summary> /// 随机返回一条数据 /// </summary> /// <param name="list"></pa ...
- Jmeter 中多线程并发和循环控制器
今天遇到一个场景, 给一个手机号发送短信验证码,通过正确输入短信验证码即登录并获得token,进行其他操作. 短信验证码是4位,即9999个组合, 接口没有对验证次数做校验,所以可以一直一直尝试通过验 ...
- Java 打开Excel,往Excel中存入值,保存的excel格式分别是xls和xlsx
https://mirrors.cnnic.cn/apache/poi/xmlbeans/release/src/ package Excel; import org.apache.poi.hssf. ...
- /etc/fstab 文件解析
首先介绍一下fstab :这个文件描述系统中各种文件系统的信息.一般而言,应用程序仅读取这个文件,而不对它进行写操作.对它的维护是系统管理员的工作.在这个文件中,每个文件系统用一行来描述,在每一行中, ...
- jdk1.8
Jdk1.8新特性 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性.在本文中我们将学习这些新特性, ...
- Redis之列表类型命令
Redis 列表(List) Redis列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素到列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (4294967 ...