Webbench学习笔记二:getopt_long函数和build_request函数

概述

上一章记录了源码的获取和使用,接下来开始记录源码分析过程。本章主要是分析main函数结构,然后具体解析下getopt_longbuild_request两个函数的主要内容。

1. main函数结构

  1. 判断传入参数的个数,如果没有参数,则打印菜单。
  2. 通过while循环检索参数,对程序进行配置。
  3. 调用build_request函数
  4. 根据设置结果,打印参数信息
  5. 调用bench函数
    在接下来的几篇文章中,主要是对上述标注的三个部分进行分析。

2.getopt_long函数

getopt_long函数原型为:

int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

程序中调用如下:

while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )

该函数分为三个部分讲解。

2.1. 函数调用的几个参数

2.1.1. argc

参数个数

2.1.2. argv

参数内容

2.1.3. optstring

“912Vfrt:p:c:?h”:程序支持的命令行短选项。也就是命令行中支持-9、-1、-2、-V、-f、-r、-t、-p、-c、-?、-h十一个短选项,其中t、p、c三个字符后面有一个冒号,表示t、p、c应带有一个参数。如Webbench学习笔记一:源码获取和使用测试运行部分使用的命令行:

webbench -c 1000 -t 60 http://test.domain.com/phpinfo.php

2.1.4. longopts

long_options:是一个option 类型的数组,表示程序支持的命令行长选项。其定义如下:

static const struct option long_options[]=
{
    {"force",no_argument,&force,1},
    {"reload",no_argument,&force_reload,1},
    {"time",required_argument,NULL,'t'},
    {"help",no_argument,NULL,'?'},
    {"http09",no_argument,NULL,'9'},
    {"http10",no_argument,NULL,'1'},
    {"http11",no_argument,NULL,'2'},
    {"get",no_argument,&method,METHOD_GET},
    {"head",no_argument,&method,METHOD_HEAD},
    {"options",no_argument,&method,METHOD_OPTIONS},
    {"trace",no_argument,&method,METHOD_TRACE},
    {"version",no_argument,NULL,'V'},
    {"proxy",required_argument,NULL,'p'},
    {"clients",required_argument,NULL,'c'},
    {NULL,0,NULL,0}
};

option定义如下:


struct option 
{  
     const char *name;  
     int         has_arg;  
     int        *flag;  
     int         val;  
}; 

(1)name:表示选项的名称,比如force,reload,time等。

(2)has_arg:表示选项后面是否携带参数。

a:  no_argument(或者是0)时   ——参数后面不跟参数值,eg: --force,--reload
b: required_argument(或者是1)时 ——参数输入格式为:--参数 值 或者 --参数=值。eg:--time=60
c: optional_argument(或者是2)时  ——参数输入格式只能为:--参数=值。这里没有用到。

(3)flag:这个参数有两个意思,空或者非空。

a:如果参数为空NULL,那么当选中某个长选项的时候,getopt_long将返回val值。 eg,可执行程序 --time,getopt_long的返回值为t.             
b:如果参数不为空,那么当选中某个长选项的时候,getopt_long将返回0,并且将flag指针参数指向val值。 eg: 可执行程序 --force=1 那么getopt_long返回值为0,并且force值为1。

(4)val:表示指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值val。

2.1.5. longindex

options_index:非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值。

2.2 四个全局变量

2.2.1. optarg

表示当前选项对应的参数值。从下面代码可以看出:

case 't': benchtime=atoi(optarg);break;
//webbench -c 1000 -t 60 http://test.domain.com/phpinfo.php
//此处即将60赋值给benchtime

2.2.2. optind

表示的是下一个将被处理到的参数在argv中的下标值。相关代码如下:

    if(optind==argc) {
        fprintf(stderr,"webbench: Missing URL!\n");
        usage();
        return 2;
    }

这个if判断在下一节的返回值说明。

2.2.3. opterr

如果opterr = 0,getopt_long遇到错误将不会输出错误信息到标准输出流。opterr在非0时,向屏幕输出错误。

程序内未使用。

2.2.4. optopt

表示没有被未标识的选项。

程序内未使用

参考链接:浅谈linux的命令行解析参数之getopt_long函数

2.3. 函数返回值

webbench -c 1000 -t 60 http://test.domain.com/phpinfo.php

while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )

这句话的意思是检索参数选项。结合
第一次执行:

opt = c			//c为支持的短选项,getopt_long返回c
optarg = 1000	//选项c对应的参数值
optind = 3		//下一个将被处理的参数下标值为3,即-t
argv[optind - 1] = 1000

第二次执行:

opt = t			//t为支持的短选项,getopt_long返回t
optarg = 60		//选项t对应的参数值
optind = 5		//下一个将被处理的参数下标值为5,即http://test.domain.com/phpinfo.php
argv[optind - 1] = 60

第三次执行:

http://test.domain.com/phpinfo.php不是支持的短选项或长选项,所以返回-1,退出while循环。
EOF实际是-1,用来表示文本文件的结束
此时optind = 5

而传入的参数个数argc=6,所以也就有了

if(optind==argc) {
    fprintf(stderr,"webbench: Missing URL!\n");
    usage();
    return 2;
}

如果执行时未传入URL,则执行两次后结束,optind、argc= 5,也就会打印错误信息:webbench: Missing URL!

参考链接:getopt和getopt_long函数

3.build_request函数

build_request函数定义和调用如下:

void build_request(const char *url)

build_request(argv[optind]);

形参为一个字符串。通过上一篇的分析可以看出,此处传入的argv[optind]即执行时的URL:http://test.domain.com/phpinfo.php

3.1.字符串相关函数

build_request函数中使用到了较多的字符串处理函数,我这里先对相关的函数进行下温习。

3.1.1.strcat

语法:

  #include <string.h>
  char *strcat( char *str1, const char *str2 );

功能:函数将字符串str2 连接到str1的末端,并返回指针str1.

3.1.2.strstr

语法:

  #include <string.h>
  char *strstr( const char *str1, const char *str2 );

功能:函数返回一个指针,它指向字符串str2 首次出现于字符串str1中的位置,如果没有找到,返回NULL。

3.1.3.strncasecmp

语法:

#include <string.h>
int strncasecmp(const char *s1, const char *s2, size_t n);

函数说明:strncasecmp()用来比较参数s1 和s2 字符串前n个字符,比较时会自动忽略大小写的差异。
返回值:若参数s1 和s2 字符串相同则返回0。s1 若大于s2 则返回大于0 的值,s1 若小于s2 则返回小于0 的值。

3.1.4.strrchr和strchr

语法:

  #include <string.h>
  char *strrchr( const char *str, int ch );
  #include <string.h>
  char *strchr( const char *str, int ch );

strrchr功能:函数返回一个指针,它指向字符ch 在字符串str末次出现的位置,如果匹配失败,返回NULL。

strchr功能:函数返回一个指向str 中ch 首次出现的位置,当没有在str 中找ch到返回NULL。

3.1.5.index

语法:

#include<strings.h>
char *index(const char *s, int c);

函数说明:
找出参数s字符串中第一个出现参数c的地址,然后将该字符串出现的地址返回。字符串结束字符(NULL)也视为字符串的一部分。

返回值:
如果找到指定的字符,则返回字符所在地址,否则返回NULL

3.1.6.strncpy

语法:

  #include <string.h>
  char *strncpy( char *to, const char *from, size_t count );

功能:将字符串from 中至多count个字符复制到字符串to中。如果字符串from 的长度小于count,其余部分用’\0’填补。返回处理完成的字符串。

3.2.

目的是对url进行处理,得到host,proxyport,request
其中request就是之后利用socket与host通信所要发送的报文。


fdopen

fopen
语法:

  #include <stdio.h>
  FILE *fopen( const char *fname, const char *mode );

fopen()函数打开由fname(文件名)指定的文件, 并返回一个关联该文件的流.如果发生错误, fopen()返回NULL. mode(方式)是用于决定文件的用途(例如 用于输入,输出,等等)

 #include <stdio.h>
FILE * fdopen(int fildes, const char * mode);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值