zoukankan      html  css  js  c++  java
  • webbench

    socket.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)
    30 {
    31     int sock;
    32     unsigned long inaddr;
    33     struct sockaddr_in ad;
    34     struct hostent *hp;
    35     
    36     memset(&ad, 0, sizeof(ad));
    37     ad.sin_family = AF_INET;
    38 
    39     inaddr = inet_addr(host);
    40     if (inaddr != INADDR_NONE)
    41         memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
    42     else
    43     {
    44         hp = gethostbyname(host);
    45         if (hp == NULL)
    46             return -1;
    47         memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
    48     }
    49     ad.sin_port = htons(clientPort);
    50     
    51     sock = socket(AF_INET, SOCK_STREAM, 0);
    52     if (sock < 0)
    53         return sock;
    54     if (connect(sock, (struct sockaddr *)&ad, sizeof(ad)) < 0)
    55         return -1;
    56     return sock;
    57 }
    View Code

    webbench.c

      1 /*
      2  * (C) Radim Kolar 1997-2004
      3  * This is free software, see GNU Public License version 2 for
      4  * details.
      5  *
      6  * Simple forking WWW Server benchmark:
      7  *
      8  * Usage:
      9  *   webbench --help
     10  *
     11  * Return codes:
     12  *    0 - sucess
     13  *    1 - benchmark failed (server is not on-line)
     14  *    2 - bad param
     15  *    3 - internal error, fork failed
     16  * 
     17  */ 
     18 #include "socket.c"
     19 #include <unistd.h>
     20 #include <sys/param.h>
     21 #include <rpc/types.h>
     22 #include <getopt.h>
     23 #include <strings.h>
     24 #include <time.h>
     25 #include <signal.h>
     26 
     27 /* values */
     28 volatile int timerexpired=0;
     29 int speed=0;
     30 int failed=0;
     31 int bytes=0;
     32 /* globals */
     33 int http10=1; /* 0 - http/0.9, 1 - http/1.0, 2 - http/1.1 */
     34 /* Allow: GET, HEAD, OPTIONS, TRACE */
     35 #define METHOD_GET 0
     36 #define METHOD_HEAD 1
     37 #define METHOD_OPTIONS 2
     38 #define METHOD_TRACE 3
     39 #define PROGRAM_VERSION "1.5"
     40 int method=METHOD_GET;
     41 int clients=1;
     42 int force=0;
     43 int force_reload=0;
     44 int proxyport=80;
     45 char *proxyhost=NULL;
     46 int benchtime=30;
     47 /* internal */
     48 int mypipe[2];
     49 char host[MAXHOSTNAMELEN];
     50 #define REQUEST_SIZE 2048
     51 char request[REQUEST_SIZE];
     52 
     53 static const struct option long_options[]=
     54 {
     55  {"force",no_argument,&force,1},
     56  {"reload",no_argument,&force_reload,1},
     57  {"time",required_argument,NULL,'t'},
     58  {"help",no_argument,NULL,'?'},
     59  {"http09",no_argument,NULL,'9'},
     60  {"http10",no_argument,NULL,'1'},
     61  {"http11",no_argument,NULL,'2'},
     62  {"get",no_argument,&method,METHOD_GET},
     63  {"head",no_argument,&method,METHOD_HEAD},
     64  {"options",no_argument,&method,METHOD_OPTIONS},
     65  {"trace",no_argument,&method,METHOD_TRACE},
     66  {"version",no_argument,NULL,'V'},
     67  {"proxy",required_argument,NULL,'p'},
     68  {"clients",required_argument,NULL,'c'},
     69  {NULL,0,NULL,0}
     70 };
     71 
     72 /* prototypes */
     73 static void benchcore(const char* host,const int port, const char *request);
     74 static int bench(void);
     75 static void build_request(const char *url);
     76 
     77 static void alarm_handler(int signal)
     78 {
     79    timerexpired=1;
     80 }    
     81 
     82 static void usage(void)
     83 {
     84    fprintf(stderr,
     85     "webbench [option]... URL
    "
     86     "  -f|--force               Don't wait for reply from server.
    "
     87     "  -r|--reload              Send reload request - Pragma: no-cache.
    "
     88     "  -t|--time <sec>          Run benchmark for <sec> seconds. Default 30.
    "
     89     "  -p|--proxy <server:port> Use proxy server for request.
    "
     90     "  -c|--clients <n>         Run <n> HTTP clients at once. Default one.
    "
     91     "  -9|--http09              Use HTTP/0.9 style requests.
    "
     92     "  -1|--http10              Use HTTP/1.0 protocol.
    "
     93     "  -2|--http11              Use HTTP/1.1 protocol.
    "
     94     "  --get                    Use GET request method.
    "
     95     "  --head                   Use HEAD request method.
    "
     96     "  --options                Use OPTIONS request method.
    "
     97     "  --trace                  Use TRACE request method.
    "
     98     "  -?|-h|--help             This information.
    "
     99     "  -V|--version             Display program version.
    "
    100     );
    101 };
    102 int main(int argc, char *argv[])
    103 {
    104  int opt=0;
    105  int options_index=0;
    106  char *tmp=NULL;
    107 
    108  if(argc==1)
    109  {
    110       usage();
    111           return 2;
    112  } 
    113 
    114  while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )
    115  {
    116   switch(opt)
    117   {
    118    case  0 : break;
    119    case 'f': force=1;break;
    120    case 'r': force_reload=1;break; 
    121    case '9': http10=0;break;
    122    case '1': http10=1;break;
    123    case '2': http10=2;break;
    124    case 'V': printf(PROGRAM_VERSION"
    ");exit(0);
    125    case 't': benchtime=atoi(optarg);break;         
    126    case 'p': 
    127          /* proxy server parsing server:port */
    128          tmp=strrchr(optarg,':');
    129          proxyhost=optarg;
    130          if(tmp==NULL)
    131          {
    132              break;
    133          }
    134          if(tmp==optarg)
    135          {
    136              fprintf(stderr,"Error in option --proxy %s: Missing hostname.
    ",optarg);
    137              return 2;
    138          }
    139          if(tmp==optarg+strlen(optarg)-1)
    140          {
    141              fprintf(stderr,"Error in option --proxy %s Port number is missing.
    ",optarg);
    142              return 2;
    143          }
    144          *tmp='';
    145          proxyport=atoi(tmp+1);break;
    146    case ':':
    147    case 'h':
    148    case '?': usage();return 2;break;
    149    case 'c': clients=atoi(optarg);break;
    150   }
    151  }
    152  
    153  if(optind==argc) {
    154                       fprintf(stderr,"webbench: Missing URL!
    ");
    155               usage();
    156               return 2;
    157                     }
    158 
    159  if(clients==0) clients=1;
    160  if(benchtime==0) benchtime=60;
    161  /* Copyright */
    162  fprintf(stderr,"Webbench - Simple Web Benchmark "PROGRAM_VERSION"
    "
    163      "Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
    "
    164      );
    165  build_request(argv[optind]);
    166  /* print bench info */
    167  printf("
    Benchmarking: ");
    168  switch(method)
    169  {
    170      case METHOD_GET:
    171      default:
    172          printf("GET");break;
    173      case METHOD_OPTIONS:
    174          printf("OPTIONS");break;
    175      case METHOD_HEAD:
    176          printf("HEAD");break;
    177      case METHOD_TRACE:
    178          printf("TRACE");break;
    179  }
    180  printf(" %s",argv[optind]);
    181  switch(http10)
    182  {
    183      case 0: printf(" (using HTTP/0.9)");break;
    184      case 2: printf(" (using HTTP/1.1)");break;
    185  }
    186  printf("
    ");
    187  if(clients==1) printf("1 client");
    188  else
    189    printf("%d clients",clients);
    190 
    191  printf(", running %d sec", benchtime);
    192  if(force) printf(", early socket close");
    193  if(proxyhost!=NULL) printf(", via proxy server %s:%d",proxyhost,proxyport);
    194  if(force_reload) printf(", forcing reload");
    195  printf(".
    ");
    196  return bench();
    197 }
    198 
    199 void build_request(const char *url)
    200 {
    201   char tmp[10];
    202   int i;
    203 
    204   bzero(host,MAXHOSTNAMELEN);
    205   bzero(request,REQUEST_SIZE);
    206 
    207   if(force_reload && proxyhost!=NULL && http10<1) http10=1;
    208   if(method==METHOD_HEAD && http10<1) http10=1;
    209   if(method==METHOD_OPTIONS && http10<2) http10=2;
    210   if(method==METHOD_TRACE && http10<2) http10=2;
    211 
    212   switch(method)
    213   {
    214       default:
    215       case METHOD_GET: strcpy(request,"GET");break;
    216       case METHOD_HEAD: strcpy(request,"HEAD");break;
    217       case METHOD_OPTIONS: strcpy(request,"OPTIONS");break;
    218       case METHOD_TRACE: strcpy(request,"TRACE");break;
    219   }
    220           
    221   strcat(request," ");
    222 
    223   if(NULL==strstr(url,"://"))
    224   {
    225       fprintf(stderr, "
    %s: is not a valid URL.
    ",url);
    226       exit(2);
    227   }
    228   if(strlen(url)>1500)
    229   {
    230          fprintf(stderr,"URL is too long.
    ");
    231      exit(2);
    232   }
    233   if(proxyhost==NULL)
    234        if (0!=strncasecmp("http://",url,7)) 
    235        { fprintf(stderr,"
    Only HTTP protocol is directly supported, set --proxy for others.
    ");
    236              exit(2);
    237            }
    238   /* protocol/host delimiter */
    239   i=strstr(url,"://")-url+3;
    240   /* printf("%d
    ",i); */
    241 
    242   if(strchr(url+i,'/')==NULL) {
    243                                 fprintf(stderr,"
    Invalid URL syntax - hostname don't ends with '/'.
    ");
    244                                 exit(2);
    245                               }
    246   if(proxyhost==NULL)
    247   {
    248    /* get port from hostname */
    249    if(index(url+i,':')!=NULL &&
    250       index(url+i,':')<index(url+i,'/'))
    251    {
    252        strncpy(host,url+i,strchr(url+i,':')-url-i);
    253        bzero(tmp,10);
    254        strncpy(tmp,index(url+i,':')+1,strchr(url+i,'/')-index(url+i,':')-1);
    255        /* printf("tmp=%s
    ",tmp); */
    256        proxyport=atoi(tmp);
    257        if(proxyport==0) proxyport=80;
    258    } else
    259    {
    260      strncpy(host,url+i,strcspn(url+i,"/"));
    261    }
    262    // printf("Host=%s
    ",host);
    263    strcat(request+strlen(request),url+i+strcspn(url+i,"/"));
    264   } else
    265   {
    266    // printf("ProxyHost=%s
    ProxyPort=%d
    ",proxyhost,proxyport);
    267    strcat(request,url);
    268   }
    269   if(http10==1)
    270       strcat(request," HTTP/1.0");
    271   else if (http10==2)
    272       strcat(request," HTTP/1.1");
    273   strcat(request,"
    ");
    274   if(http10>0)
    275       strcat(request,"User-Agent: WebBench "PROGRAM_VERSION"
    ");
    276   if(proxyhost==NULL && http10>0)
    277   {
    278       strcat(request,"Host: ");
    279       strcat(request,host);
    280       strcat(request,"
    ");
    281   }
    282   if(force_reload && proxyhost!=NULL)
    283   {
    284       strcat(request,"Pragma: no-cache
    ");
    285   }
    286   if(http10>1)
    287       strcat(request,"Connection: close
    ");
    288   /* add empty line at end */
    289   if(http10>0) strcat(request,"
    "); 
    290   // printf("Req=%s
    ",request);
    291 }
    292 
    293 /* vraci system rc error kod */
    294 static int bench(void)
    295 {
    296   int i,j,k;    
    297   pid_t pid=0;
    298   FILE *f;
    299 
    300   /* check avaibility of target server */
    301   i=Socket(proxyhost==NULL?host:proxyhost,proxyport);
    302   if(i<0) { 
    303        fprintf(stderr,"
    Connect to server failed. Aborting benchmark.
    ");
    304            return 1;
    305          }
    306   close(i);
    307   /* create pipe */
    308   if(pipe(mypipe))
    309   {
    310       perror("pipe failed.");
    311       return 3;
    312   }
    313 
    314   /* not needed, since we have alarm() in childrens */
    315   /* wait 4 next system clock tick */
    316   /*
    317   cas=time(NULL);
    318   while(time(NULL)==cas)
    319         sched_yield();
    320   */
    321 
    322   /* fork childs */
    323   for(i=0;i<clients;i++)
    324   {
    325        pid=fork();
    326        if(pid <= (pid_t) 0)
    327        {
    328            /* child process or error*/
    329                sleep(1); /* make childs faster */
    330            break;
    331        }
    332   }
    333 
    334   if( pid< (pid_t) 0)
    335   {
    336           fprintf(stderr,"problems forking worker no. %d
    ",i);
    337       perror("fork failed.");
    338       return 3;
    339   }
    340 
    341   if(pid== (pid_t) 0)
    342   {
    343     /* I am a child */
    344     if(proxyhost==NULL)
    345       benchcore(host,proxyport,request);
    346          else
    347       benchcore(proxyhost,proxyport,request);
    348 
    349          /* write results to pipe */
    350      f=fdopen(mypipe[1],"w");
    351      if(f==NULL)
    352      {
    353          perror("open pipe for writing failed.");
    354          return 3;
    355      }
    356      /* fprintf(stderr,"Child - %d %d
    ",speed,failed); */
    357      fprintf(f,"%d %d %d
    ",speed,failed,bytes);
    358      fclose(f);
    359      return 0;
    360   } else
    361   {
    362       f=fdopen(mypipe[0],"r");
    363       if(f==NULL) 
    364       {
    365           perror("open pipe for reading failed.");
    366           return 3;
    367       }
    368       setvbuf(f,NULL,_IONBF,0);
    369       speed=0;
    370           failed=0;
    371           bytes=0;
    372 
    373       while(1)
    374       {
    375           pid=fscanf(f,"%d %d %d",&i,&j,&k);
    376           if(pid<2)
    377                   {
    378                        fprintf(stderr,"Some of our childrens died.
    ");
    379                        break;
    380                   }
    381           speed+=i;
    382           failed+=j;
    383           bytes+=k;
    384           /* fprintf(stderr,"*Knock* %d %d read=%d
    ",speed,failed,pid); */
    385           if(--clients==0) break;
    386       }
    387       fclose(f);
    388 
    389   printf("
    Speed=%d pages/min, %d bytes/sec.
    Requests: %d susceed, %d failed.
    ",
    390           (int)((speed+failed)/(benchtime/60.0f)),
    391           (int)(bytes/(float)benchtime),
    392           speed,
    393           failed);
    394   }
    395   return i;
    396 }
    397 
    398 void benchcore(const char *host,const int port,const char *req)
    399 {
    400  int rlen;
    401  char buf[1500];
    402  int s,i;
    403  struct sigaction sa;
    404 
    405  /* setup alarm signal handler */
    406  sa.sa_handler=alarm_handler;
    407  sa.sa_flags=0;
    408  if(sigaction(SIGALRM,&sa,NULL))
    409     exit(3);
    410  alarm(benchtime);
    411 
    412  rlen=strlen(req);
    413  nexttry:while(1)
    414  {
    415     if(timerexpired)
    416     {
    417        if(failed>0)
    418        {
    419           /* fprintf(stderr,"Correcting failed by signal
    "); */
    420           failed--;
    421        }
    422        return;
    423     }
    424     s=Socket(host,port);                          
    425     if(s<0) { failed++;continue;} 
    426     if(rlen!=write(s,req,rlen)) {failed++;close(s);continue;}
    427     if(http10==0) 
    428         if(shutdown(s,1)) { failed++;close(s);continue;}
    429     if(force==0) 
    430     {
    431             /* read all available data from socket */
    432         while(1)
    433         {
    434               if(timerexpired) break; 
    435           i=read(s,buf,1500);
    436               /* fprintf(stderr,"%d
    ",i); */
    437           if(i<0) 
    438               { 
    439                  failed++;
    440                  close(s);
    441                  goto nexttry;
    442               }
    443            else
    444                if(i==0) break;
    445                else
    446                    bytes+=i;
    447         }
    448     }
    449     if(close(s)) {failed++;continue;}
    450     speed++;
    451  }
    452 }
    View Code

    Makefile

     1 CFLAGS?=    -Wall -ggdb -W -O
     2 CC?=        gcc
     3 LIBS?=
     4 LDFLAGS?=
     5 PREFIX?=    /usr/local
     6 VERSION=1.5
     7 TMPDIR=/tmp/webbench-$(VERSION)
     8 
     9 #all:   webbench tags
    10 all:   webbench
    11 
    12 #tags:  *.c
    13 #    -ctags *.c
    14 
    15 install: webbench
    16     install -s webbench $(DESTDIR)$(PREFIX)/bin    
    17     install -m 644 webbench.1 $(DESTDIR)$(PREFIX)/man/man1    
    18     install -d $(DESTDIR)$(PREFIX)/share/doc/webbench
    19     install -m 644 debian/copyright $(DESTDIR)$(PREFIX)/share/doc/webbench
    20     install -m 644 debian/changelog $(DESTDIR)$(PREFIX)/share/doc/webbench
    21 
    22 webbench: webbench.o Makefile
    23     $(CC) $(CFLAGS) $(LDFLAGS) -o webbench webbench.o $(LIBS) 
    24 
    25 clean:
    26     -rm -f *.o webbench *~ core *.core
    27 #    -rm -f *.o webbench *~ core *.core tags
    28     
    29 tar:   clean
    30     -debian/rules clean
    31     rm -rf $(TMPDIR)
    32     install -d $(TMPDIR)
    33     cp -p Makefile webbench.c socket.c webbench.1 $(TMPDIR)
    34     install -d $(TMPDIR)/debian
    35     -cp -p debian/* $(TMPDIR)/debian
    36     ln -sf debian/copyright $(TMPDIR)/COPYRIGHT
    37     ln -sf debian/changelog $(TMPDIR)/ChangeLog
    38     -cd $(TMPDIR) && cd .. && tar cozf webbench-$(VERSION).tar.gz webbench-$(VERSION)
    39 
    40 webbench.o:    webbench.c socket.c Makefile
    41 
    42 .PHONY: clean install all tar
    View Code

  • 相关阅读:
    Server Develop (三) 多进程实现C/S
    Server Develop (二) 多线程实现C/S
    Server Develop (一) 简单的TCP/IP C/S
    Server Develop (四) select实现非阻塞sever
    js添加、修改、删除xml节点例子
    网站弹出“位于Google Code SubversionRepository 的服务器……”的解决办法
    iframe嵌入网页
    asp空间判断jmail组件是否安装或支持的代码
    IE8的margintop兼容问题
    不错的CMS,值得借鉴!
  • 原文地址:https://www.cnblogs.com/guxuanqing/p/5782542.html
Copyright © 2011-2022 走看看