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)) != -1){
        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 0;
 }

 编译运行: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, 0, NULL, 0} };
// 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 = 0; int opt = 0; int options_index = 0; opterr = 0; if(argc == 1){ usage(); return 0; } while((opt = getopt_long(argc,argv,short_opt,long_opts,&options_index)) != -1) { switch(opt) { case 'h': hflag = 1;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 1; 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 1; } if(!output_name){ printf("Error: output name must be specified\n"); return 1; } // 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 0; }

 编译运行

 

后记:

 

奈何、奈何

 

冷冬悲苦心怅惘,强颜欢笑几人懂

我愿长醉不复醒,此恨缠绵无绝期

幽幽地冥十二刹,牛马铁索心上寒

惶惶炼狱十八层, 阎罗判官不作解

奈何桥畔花落去,痴情不饮孟婆汤

今生无缘比翼飞,来世连理在枝头

可笑命运太无常,不胜梦中一场醉

伊人一笑解千愁,弹指一挥岁月老

花开叶落终有期,心碎这般若止水

人间对错本无界,何不把酒话桑麻

问君此生何所憾,淡然一笑把话藏

瑶琴一把指上弹,愿卿为我座上听

年少白衣曾不羁,情为何物惹乡愁

无端由来一场梦,为你走马到天涯

世间万物不足提,唯愿与卿到白首

前路荆棘何所惧,彼岸花香待芳华

我耕你织笑无言,默然相守无所求

闲来无事画碧楼,玉阶微凉夜雪飞

一壶浊酒醉明月,与卿笑谈天下事

风扶雪花翩翩舞,月光星华照无眠

此景只应梦中有,何期与共今宵逢

执子之手私语时,满地黄花不抬头

多情总被无情恼,相逢何必曾相识

待到如梦初醒时,不得落笔已成殇

飘飘兮

如流风之回雪

寥寥兮

似长空之燕不归

呜呼

哀哉

奈何、奈何

posted @ 2018-07-09 16:43  牧羊少年Zhao  阅读(429)  评论(0编辑  收藏  举报