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++作业:Circle_area
Github链接: Circle_area 代码: main.cpp #include "circle_area.h" #include <iostream> #inc ...
- miRNA几大常用的数据库
1.miRbasehttp://www.mirbase.org/2.miRDBhttp://www.mirdb.org/miRDB/policy.html3.miRandahttp://www.mic ...
- python pstats ,profile 性能分析
#! /usr/bin/env python # encoding=utf8 import pstats import profile def func1(): for i in range(1000 ...
- sqlserver 存入DB中的中文乱码
在war包中的appliation.properties中,配置的数据库连接做了修改,也不知道当初为什么这么改 导致存入DB中的中文是??? testaaa.jdbc.type=mssqltestaa ...
- MyEclipse2014 优化设置
1.指定本机java环境 Windows-->preferences-->java-->Insetallel JREs 右侧 单击ADD standard VM-->Next ...
- 《剑指offer》第二十五题(合并两个排序的链表)
// 面试题25:合并两个排序的链表 // 题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按 // 照递增排序的.例如输入图3.11中的链表1和链表2,则合并之后的升序链表如链 ...
- 网站链接facebook 拿新的post
$http({ method: "GET", url: "https://graph.facebook.com/oauth/access_token?client_id= ...
- 快速搭建一个简易的KMS 服务
xu言: 之前,闹的沸沸扬扬的KMS激活工具自身都存在问题的事.让我们对以前的什么小马激活.kms激活.各种激活工具都去打了一个深深的“?”,到底哪些能用.哪些不能用.有些还注明的里面必须要关闭杀毒软 ...
- codeforces 993c//Careful Maneuvering// Codeforces Round #488 by NEAR (Div. 1)
题意:x轴-100和+100的有敌人飞船,纵坐标由输入数据给出,我方有2飞船在x轴0,y坐标待定.0时刻时敌人同时向我方2飞船发出光线,光线会穿透飞船打到敌人自己,问2飞船放在哪敌人损失最大? 假如- ...
- Thrift0.11.0基于Intellij IDEA的简单的例子
前言 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等.其中所用到的数据传输方式包括 XML,JSON 等,然 ...