【OpenSource】源码--Web Bench 1.5

源码:

Web Bench 1.5介绍 html

1.用GDB单步走的,走了父进程也走了子进程。父进程负责从管道里读取数据,每一个子进程通过socket,connect,write,read,负责Get请求写数据到管道。子进程至关于socket网络编程里的client客户端。web

2.GDB调试时,经过设置set follow-fork-mode [parent][child]分别执行父子进程。编程

3.调试时输入指令为:-c 10 -t 5 http://www.baidu.com/数组

4.代码很少可是牵扯的东西仍是很多的。建议本身跟一边。服务器

  1 /*
  2  * Return codes:
  3  *    0 - sucess
  4  *    1 - benchmark failed (server is not on-line)
  5  *    2 - bad param
  6  *    3 - internal error, fork failed
  7  */ 
  8 #include "socket.c"
  9 #include <unistd.h>
 10 #include <sys/param.h>
 11 #include <rpc/types.h>    //pid_t
 12 #include <getopt.h>
 13 #include <strings.h>
 14 #include <time.h>
 15 #include <signal.h>
 16 
 17 /* values */
 18 volatile int timerexpired=0;    //volatile 在多进程中,变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以避免出错  http://www.cnblogs.com/chio/archive/2007/11/24/970632.html
 19 int speed=0;
 20 int failed=0;
 21 int bytes=0;
 22 /* globals */
 23 int http10=1; /* 0 - http/0.9, 1 - http/1.0, 2 - http/1.1 */
 24 /* Allow: GET, HEAD, OPTIONS, TRACE */
 25 #define METHOD_GET 0
 26 #define METHOD_HEAD 1
 27 #define METHOD_OPTIONS 2
 28 #define METHOD_TRACE 3
 29 #define PROGRAM_VERSION "1.5"
 30 int method=METHOD_GET;
 31 int clients=1;
 32 int force=0;
 33 int force_reload=0;
 34 int proxyport=80;
 35 char *proxyhost=NULL;
 36 int benchtime=30;
 37 /* internal */
 38 int mypipe[2];
 39 char host[MAXHOSTNAMELEN];
 40 #define REQUEST_SIZE 2048
 41 char request[REQUEST_SIZE];
 42 
 43 static const struct option long_options[]=
 44 {
 45  {"force",no_argument,&force,1},
 46  {"reload",no_argument,&force_reload,1},
 47  {"time",required_argument,NULL,'t'},
 48  {"help",no_argument,NULL,'?'},
 49  {"http09",no_argument,NULL,'9'},
 50  {"http10",no_argument,NULL,'1'},
 51  {"http11",no_argument,NULL,'2'},
 52  {"get",no_argument,&method,METHOD_GET},
 53  {"head",no_argument,&method,METHOD_HEAD},
 54  {"options",no_argument,&method,METHOD_OPTIONS},
 55  {"trace",no_argument,&method,METHOD_TRACE},
 56  {"version",no_argument,NULL,'V'},
 57  {"proxy",required_argument,NULL,'p'},
 58  {"clients",required_argument,NULL,'c'},
 59  {NULL,0,NULL,0}
 60 };
 61 
 62 /* prototypes */
 63 static void benchcore(const char* host,const int port, const char *request);
 64 static int bench(void);
 65 static void build_request(const char *url);
 66 
 67 static void alarm_handler(int signal)
 68 {
 69    timerexpired=1;
 70 }    
 71 
 72 static void usage(void)
 73 {
 74    fprintf(stderr,
 75     "webbench [option]... URL\n"
 76     "  -f|--force               Don't wait for reply from server.\n"
 77     "  -r|--reload              Send reload request - Pragma: no-cache.\n"
 78     "  -t|--time <sec>          Run benchmark for <sec> seconds. Default 30.\n"
 79     "  -p|--proxy <server:port> Use proxy server for request.\n"
 80     "  -c|--clients <n>         Run <n> HTTP clients at once. Default one.\n"
 81     "  -9|--http09              Use HTTP/0.9 style requests.\n"
 82     "  -1|--http10              Use HTTP/1.0 protocol.\n"
 83     "  -2|--http11              Use HTTP/1.1 protocol.\n"
 84     "  --get                    Use GET request method.\n"
 85     "  --head                   Use HEAD request method.\n"
 86     "  --options                Use OPTIONS request method.\n"
 87     "  --trace                  Use TRACE request method.\n"
 88     "  -?|-h|--help             This information.\n"
 89     "  -V|--version             Display program version.\n"
 90     );
 91 };
 92 int main(int argc, char *argv[])
 93 {
 94  int opt=0;
 95  int options_index=0;
 96  char *tmp=NULL;
 97 
 98  if(argc==1)
 99  {
100       usage();
101           return 2;
102  } 
103 
104  while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )
105  {
106   switch(opt)
107   {
108    case  0 : break;
109    case 'f': force=1;break;
110    case 'r': force_reload=1;break; 
111    case '9': http10=0;break;
112    case '1': http10=1;break;
113    case '2': http10=2;break;
114    case 'V': printf(PROGRAM_VERSION"\n");exit(0);
115    case 't': benchtime=atoi(optarg);break;         
116    case 'p': 
117          /* proxy server parsing server:port */
118          tmp=strrchr(optarg,':');
119          proxyhost=optarg;
120          if(tmp==NULL)
121          {
122              break;
123          }
124          if(tmp==optarg)
125          {
126              fprintf(stderr,"Error in option --proxy %s: Missing hostname.\n",optarg);
127              return 2;
128          }
129          if(tmp==optarg+strlen(optarg)-1)
130          {
131              fprintf(stderr,"Error in option --proxy %s Port number is missing.\n",optarg);
132              return 2;
133          }
134          *tmp='\0';
135          proxyport=atoi(tmp+1);break;
136    case ':':
137    case 'h':
138    case '?': usage();return 2;break;
139    case 'c': clients=atoi(optarg);break;
140   }
141  }
142  
143  if(optind==argc) {
144                       fprintf(stderr,"webbench: Missing URL!\n");
145               usage();
146               return 2;
147                     }
148 
149  if(clients==0) clients=1;
150  if(benchtime==0) benchtime=60;
151  /* Copyright */
152  fprintf(stderr,"Webbench - Simple Web Benchmark "PROGRAM_VERSION"\n"
153      "Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.\n"
154      );
155  build_request(argv[optind]);//传送url    //结果:request = "GET // HTTP/1.0 HTTP/1.0 HTTP/1.0\r\nUser-Agent: WebBench 1.5\r\nHost: www.baidu.com\r\n\r\n"
156  /* print bench info */
157  printf("\nBenchmarking: ");
158  switch(method)
159  {
160      case METHOD_GET:
161      default:
162          printf("GET");break;
163      case METHOD_OPTIONS:
164          printf("OPTIONS");break;
165      case METHOD_HEAD:
166          printf("HEAD");break;
167      case METHOD_TRACE:
168          printf("TRACE");break;
169  }
170  printf(" %s",argv[optind]);    //argv[optind] 为 "http://www.baidu.com/"
171  switch(http10)        //http10==1不执行
172  {
173      case 0: printf(" (using HTTP/0.9)");break;
174      case 2: printf(" (using HTTP/1.1)");break;
175  }
176  printf("\n");
177  if(clients==1) printf("1 client");
178  else
179    printf("%d clients",clients);    //
180 
181  printf(", running %d sec", benchtime);    //
182  if(force) printf(", early socket close");
183  if(proxyhost!=NULL) printf(", via proxy server %s:%d",proxyhost,proxyport);
184  if(force_reload) printf(", forcing reload");
185  printf(".\n");
186  return bench();
187 }
188 
189 void build_request(const char *url)
190 {
191   char tmp[10];
192   int i;
193 
194   bzero(host,MAXHOSTNAMELEN);    //函数原型 void bzero(void *s,int n)将s所指的区域前n个字节置为零
195   bzero(request,REQUEST_SIZE);
196 
197   if(force_reload && proxyhost!=NULL && http10<1) http10=1;
198   if(method==METHOD_HEAD && http10<1) http10=1;
199   if(method==METHOD_OPTIONS && http10<2) http10=2;
200   if(method==METHOD_TRACE && http10<2) http10=2;
201 
202   switch(method)
203   {
204       default:
205       case METHOD_GET: strcpy(request,"GET");break;
206       case METHOD_HEAD: strcpy(request,"HEAD");break;
207       case METHOD_OPTIONS: strcpy(request,"OPTIONS");break;
208       case METHOD_TRACE: strcpy(request,"TRACE");break;
209   }
210           
211   strcat(request," ");
212 
213   if(NULL==strstr(url,"://"))//函数原型:extern char *strstr(char *str1,char *str2)返回str2(不包括\0)在str1中的位置,没有则返回NULL
214   {
215       fprintf(stderr, "\n%s: is not a valid URL.\n",url);
216       exit(2);
217   }
218   if(strlen(url)>1500)
219   {
220          fprintf(stderr,"URL is too long.\n");
221      exit(2);
222   }
223   if(proxyhost==NULL)
224        if (0!=strncasecmp("http://",url,7)) 
225        {
226                fprintf(stderr,"\nOnly HTTP protocol is directly supported, set --proxy for others.\n");
227             exit(2);
228        }
229   /* protocol/host delimiter分隔符 */
230   i=strstr(url,"://")-url+3;//去掉http://得www.aa.com/
231   /* printf("%d\n",i); */
232 
233   if(strchr(url+i,'/')==NULL)     //查找某字符在字符串首次出现的位置
234   {
235      fprintf(stderr,"\nInvalid URL syntax - hostname don't ends with '/'.\n");
236      exit(2);
237   }
238   if(proxyhost==NULL)
239   {
240    /* get port from hostname */
241    if(index(url+i,':')!=NULL &&
242       index(url+i,':')<index(url+i,'/'))    //函数原型char *index(const char*s,char c)返回c在s中的索引
243    {
244        strncpy(host,url+i,strchr(url+i,':')-url-i);
245        bzero(tmp,10);
246        strncpy(tmp,index(url+i,':')+1,strchr(url+i,'/')-index(url+i,':')-1);
247        /* printf("tmp=%s\n",tmp); */
248        proxyport=atoi(tmp);
249        if(proxyport==0) proxyport=80;
250    } 
251    else
252    {// 函数原型char * strncpy(char *dest,const char *src,size_t n);复制目标字符串src的前n个字符到dest    //函数原型int strcspn(char *str,char *accept);返回字符串str开头连续不含字符串accept内的字符数目 如 www.baidu.com/ 返回13*/
253    strncpy(host,url+i,strcspn(url+i,"/"));
254    }
255    // printf("Host=%s\n",host);
256    strcat(request+strlen(request),url+i+strcspn(url+i,"/"));    //request=="GET //"
257   } 
258   else
259   {
260    // printf("ProxyHost=%s\nProxyPort=%d\n",proxyhost,proxyport);
261    strcat(request,url);
262   }
263   if(http10==1)
264       strcat(request," HTTP/1.0");    //"GET // HTTP/1.0 HTTP/1.0 HTTP/1.0"
265   else if (http10==2)
266       strcat(request," HTTP/1.1");
267   strcat(request,"\r\n");
268   if(http10>0)
269       strcat(request,"User-Agent: WebBench "PROGRAM_VERSION"\r\n");//"GET // HTTP/1.0 HTTP/1.0 HTTP/1.0\r\nUser-Agent: WebBench 1.5\r\n"
270   if(proxyhost==NULL && http10>0)
271   {
272       strcat(request,"Host: ");
273       strcat(request,host);
274       strcat(request,"\r\n");    //request = "GET // HTTP/1.0 HTTP/1.0 HTTP/1.0\r\nUser-Agent: WebBench 1.5\r\nHost: www.baidu.com\r\n"
275   }
276   if(force_reload && proxyhost!=NULL)
277   {
278       strcat(request,"Pragma: no-cache\r\n");
279   }
280   if(http10>1)
281       strcat(request,"Connection: close\r\n");
282   /* add empty line at end */
283   if(http10>0) strcat(request,"\r\n"); 
284   // printf("Req=%s\n",request);
285 }
286 
287 /* vraci system rc error kod */
288 static int bench(void)
289 {
290   int i,j,k;    
291   pid_t pid=0;
292   FILE *f;
293 
294   /* check avaibility of target server */
295   i=Socket(proxyhost==NULL?host:proxyhost,proxyport);    //i==3
296   if(i<0) { 
297        fprintf(stderr,"\nConnect to server failed. Aborting benchmark.\n");
298            return 1;
299          }
300   close(i);
301   /* create pipe */
302   if(pipe(mypipe))    //建立管道 返回值==0  filedes[0]为管道里的读取端filedes[1]则为管道的写入端
303   {
304       perror("pipe failed.");
305       return 3;
306   }
307 
308   /* not needed, since we have alarm() in childrens */
309   /* wait 4 next system clock tick */
310   /*
311   cas=time(NULL);
312   while(time(NULL)==cas)
313         sched_yield();
314   */
315 
316   /* fork childs */
317   for(i=0;i<clients;i++)
318   {    //进入gdb时经过设置 set follow-fork-mode [parent][child]来选择调试父进程或子进程
319        pid=fork();    //fork()函数产生子进程分别执行下面的代码.父进程返回子进程pid>0,子进程返回0,失败返回-1
320        if(pid <= (pid_t) 0)    //调试子进程时pid==0,进入if.若调试父进程不进入if
321        {
322            /* child process or error*/
323                sleep(1); /* make childs faster */
324            break;
325        }
326   }
327 
328   if( pid< (pid_t) 0)
329   {
330           fprintf(stderr,"problems forking worker no. %d\n",i);
331       perror("fork failed.");
332       return 3;
333   }
334 
335   if(pid== (pid_t) 0)
336   {
337     /* I am a child */
338     if(proxyhost==NULL)
339       benchcore(host,proxyport,request);
340          else
341       benchcore(proxyhost,proxyport,request);
342 
343          /* write results to pipe */
344      f=fdopen(mypipe[1],"w");
345      if(f==NULL)
346      {
347          perror("open pipe for writing failed.");
348          return 3;
349      }
350      /* fprintf(stderr,"Child - %d %d\n",speed,failed); */
351      fprintf(f,"%d %d %d\n",speed,failed,bytes);
352      fclose(f);
353      return 0;
354   } 
355   else
356   {
357       f=fdopen(mypipe[0],"r");    //FILE *fdopen(int filedes,const char *type)用于在一个已经打开的文件描述符(参数1)上按哪一种方式(参数2)打开一个流
358       if(f==NULL) 
359       {
360           perror("open pipe for reading failed.");
361           return 3;
362       }
363       setvbuf(f,NULL,_IONBF,0);    //为流指定缓冲区。参数1,指定流指针。参数2,为NULL函数自动分配缓冲区。_IONBF表示不使用缓冲区,真是醉了,当即写每次I/O操做
364       speed=0;
365           failed=0;
366           bytes=0;
367     //{i,j,k,speed,failed,bytes,pid} = {10, -1073745752, -1208015616, 0, 0, 0, 10752}
368       while(1)
369       {
370           pid=fscanf(f,"%d %d %d",&i,&j,&k);    //从流中读取格式化数据。返回成功添加到参数列表元素的数目 pid:7328变为3
371           if(pid<2)
372                   {
373                        fprintf(stderr,"Some of our childrens died.\n");
374                        break;
375                   }
376           speed+=i;
377           failed+=j;
378           bytes+=k;    //{speed, failed,bytes} = {41, 0, 4077115}
379           /* fprintf(stderr,"*Knock* %d %d read=%d\n",speed,failed,pid); */
380           if(--clients==0) break;
381       }
382       fclose(f);
383     //{i,j,k,speed,failed,bytes,pid} = {2, 0, 6041, 141, 0, 1871545, 3}
384   printf("\nSpeed=%d pages/min, %d bytes/sec.\nRequests: %d susceed, %d failed.\n",
385           (int)((speed+failed)/(benchtime/60.0f)),
386           (int)(bytes/(float)benchtime),
387           speed,
388           failed);
389   }
390   return i;
391 }
392 
393 void benchcore(const char *host,const int port,const char *req)
394 {
395  int rlen;
396  char buf[1500];
397  int s,i;
398  struct sigaction sa;    //信号产生时触发某些动做咱们就能够安装信号。sigaction安装时有3个参数第一个参数是信号的值,第二个是sigaction结构这个结构说明了信号发生时调用的函数和其它的一些信息:sa_handler =<alarm_handler>,sa_mask = 3085037896...sa_flags = 0, sa_restorer = 0x0}
399 
400  /* setup alarm signal handler */
401  sa.sa_handler=alarm_handler;    //alarm_handler警报处理过程
402  sa.sa_flags=0;
403  if(sigaction(SIGALRM,&sa,NULL))
404     exit(3);
405  alarm(benchtime);//系统中的每一个进程都有一个私有的闹钟。这个闹钟很像一个计时器,能够设置在必定秒数后闹钟。时间一到,时钟就发送一个信号SIGALRM到进程。
406 
407  rlen=strlen(req);
408  nexttry:while(1)
409  {
410     if(timerexpired)    //定时1s超时退出,gdb调试的时候注意不要超时
411     {
412        if(failed>0)
413        {
414           /* fprintf(stderr,"Correcting failed by signal\n"); */
415           failed--;
416        }
417        return;
418     }
419     s=Socket(host,port);
420     if(s<0) { failed++;continue;} 
421     if(rlen!=write(s,req,rlen)) {failed++;close(s);continue;}    //rlen == 65  write()
422     if(http10==0) 
423         if(shutdown(s,1)) { failed++;close(s);continue;}
424     if(force==0) 
425     {
426             /* read all available data from socket */
427         while(1)
428         {
429               if(timerexpired) break;     //gdb:set var timerexpired=0,防止超时退出
430           i=read(s,buf,1500);        //从缓冲区读取数据read()
431               /* fprintf(stderr,"%d\n",i); */
432           if(i<0) 
433               { 
434                  failed++;
435                  close(s);
436                  goto nexttry;
437               }
438            else
439                if(i==0) break;
440                else
441                    bytes+=i;
442         }
443     }
444     if(close(s)) {failed++;continue;}
445     speed++;
446  }
447 }
webbench.c
 1 /* $Id: socket.c 1.1 1995/01/01 07:11:14 cthuang Exp $
 2  *
 3  * This module has been modified by Radim Kolar for OS/2 emx
 4  */
 5 
 6 /***********************************************************************
 7   module:       socket.c
 8   program:      popclient
 9   SCCS ID:      @(#)socket.c    1.5  4/1/94
10   programmer:   Virginia Tech Computing Center
11   compiler:     DEC RISC C compiler (Ultrix 4.1)
12   environment:  DEC Ultrix 4.3 
13   description:  UNIX sockets code.
14  ***********************************************************************/
15 
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <fcntl.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
21 #include <netdb.h>
22 #include <sys/time.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
28 
29 int Socket(const char *host, int clientPort)    //host==www.baidu.com port==80
30 {
31     int sock;
32     unsigned long inaddr;
33     struct sockaddr_in ad;
34     struct hostent *hp;
35     
36     //{ad} = {{sin_family = 2, sin_port = 0, sin_addr = {s_addr = 0}, 
37     
38     memset(&ad, 0, sizeof(ad));
39     ad.sin_family = AF_INET;
40 
41     inaddr = inet_addr(host);
42     if (inaddr != INADDR_NONE)
43         memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
44     else
45     {
46         hp = gethostbyname(host);
47         if (hp == NULL)
48             return -1;
49         memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
50     }
51     ad.sin_port = htons(clientPort);
52     //ad = {sin_family = 2, sin_port = 20480, sin_addr = {s_addr = 2471192266}
53     sock = socket(AF_INET, SOCK_STREAM, 0);    //sock==3n
54     if (sock < 0)
55         return sock;
56     if (connect(sock, (struct sockaddr *)&ad, sizeof(ad)) < 0)
57         return -1;
58     return sock;
59 } 
60 /*----------------------------------------------------------------------
61  请求链接的客户端套接字(client端):
62 1.调用socket函数建立套接字:int socket(int domain, int type, int protocol)    //成功返回文件描述符,失败返回-1
63 2.调用connect函数向服务器端发送链接请求:int connect(int sockfd,  struct sockaddr* serveraddr, socklen_t addrlen)    //链接时serveraddr
64 3.read()/write():数据交换
65 4.close函数关闭链接
66 ----------------------------------------------------------------------*/
socket.c

头文件

include<getopt.h>//功能:主要用来处理接受的命令行参数argc,argv[]。函数主要包括getopt()和getopt_long(),不用本身处理用户输入的命令行参数了。网络

[指令]webbench -c 10 -t 20 http://www.baidu.com/  其中argc==6从1开始计数,argv[0-5]分别==webbench -c 10 -t 20 http://...从0开始计数数据结构

getopt()函数原型:int getopt(int argc,char *const argv[],const char *optstring);dom

全局变量 extern char *optarg; extern int optind, opterr, optopt; optarg选项的参数指针,optind这个索引指向argv里当前分析的字符串的下一个索引。socket

getopt()处理以-开头的命令行参数,如optstring="912Vfrt:p:c:?h"表示-9 -V -f -p -c -tide

调用该函数一次返回一个选项,直到结束返回-1。

getopt_long()函数原型:int getopt_long(int argc,char *const argv[],const char *optstring,const struct option *longopts,

int *longindex);
while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) 

webbench中为:

while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )//:后表明须要参数

struct option 类型数组
       该数据结构中的每一个元素对应了一个长选项,而且每一个元素是由四个域组成。一般状况下,能够按如下规则使用。第一个元素,描述长选项的名称;第二个选项,表明 该选项是否须要跟着参数,须要参数则为1,反之为0。no_argument 0 选项没有参数 required_argument 1 选项须要参数 optional_argument 2 选项参数是可选的;第三个选项,能够赋为NULL;第四个选项,是该长选项对应的短选项名称。另外,数据结构的最后一个元素,要求全部域的内容均为0,即{NULL,0,NULL,0}。

longopts是一个struct结构体实例,webbench中为:

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} };
main函数中,int options_index=0;
 
默认的测试时间:30s,主要是给子进程的闹钟,时间到了timerexpired会置1,从内存读的。

父进程与子进程通讯经过管道进行通讯:
1. mypipe[0] : 是读的管道端口;
2. mypipe[1] : 是写的管道端口;
alarm_handler函数功能:
1. 闹钟信号处理函数,当时间到了的时候,timerexpired被置1,表示时间到了;
2. benchcore()中会根据timerexpired值来判断子进程的运行;

 建立发送给http服务器的请求头

 

 

612      * Socket函数完成的工做:
613      *     1. 转换IP,域名,填充struct sockaddr_in,获取对应的socket描述符;
614      *     2. 链接服务器;

 

578  * bench函数完成如下功能:
579  *     1. 试探性的尝试一次是否可以正常链接服务器,若是链接失败,也就不必继续后续处理了;
580  *     2. 建立管道,用于父子进程通讯;
581  *     3. 建立clients对应数量的子进程;
582  *     4. 子进程:
583  *         1. 对服务器进行benchtime秒的链接访问,获取对应的failed,speed,bytes值;
584  *         2. 当时间到了benchtime秒之后,打开写管道;
585  *         3. 将子进程本身测试获得的failed,speed,bytes值发送给父进程;
586  *         4. 关闭写管道文件描述符;
587  *     5. 父进程:
588  *         1. 打开读管道;
589  *         2. 设置管道一些参数,初始化父进程的failed,speed,bytes变量;
590  *         3. while循环不断去获取子进程传输过来的数据,直到子进程所有退出;
591  *         4. 关闭读管道;
592  *         5. 对数据进行处理,并打印输出;
593  */

 

 

740  * benchcore函数完成功能:
741  *     1. 注册闹钟处理函数,设置闹钟时间,具体时间由benchtime给出,默认是30s;
742  *     2. while循环里判断闹钟时间是否到了,若是到了退出循环;
743  *     3. while循环里链接服务器;
744  *     4. while循环里发送http请求头给服务器;
745  *     5. while循环里判断是否须要接受服务器数据;
746  *     6. 关闭与服务器的链接;
747  *     7. 在整个过程当中,如下变量会统计在benchtime给出的时间内的一些信息:
748  *         1. failed : 链接服务器失败和传输数据过程当中失败的链接数;
749  *         2. speed  : 正常链接服务器,而且正常传输数据的链接数
750  *         3. bytes  : 从服务器获取到的字节数;
751  */
相关文章
相关标签/搜索