【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  */
相關文章
相關標籤/搜索