Source Reading notes: webbench-1.5

Source: Internet
Author: User
Tags benchmark cas

Re-layout The source code, easy to read:
/* * (C) Radim Kolar 1997-2004 * This is the free software and see the GNU public License version 2 for * details. * Simple forking WWW Server Benchmark: * * Usage: * webbench--help * * Return Codes: * 0-sucess * 1-benchma RK failed (server is not on-line) * 2-bad param * 3-internal error, fork failed * */#include "socket.c" #includ E <unistd.h> #include <sys/param.h> #include <rpc/types.h> #include <getopt.h> #include < strings.h> #include <time.h> #include <signal.h>/* timeout token, when set to 1 o'clock, all child processes exit */volatile int timerexpired=0;/ * Number of Successful requests */int speed = 0;/* Failed requests */int failed = 0;/* Read Bytes total */int bytes = 0;/* control of HTTP protocol version */int HTTP10 = 1; /* 0-http/0.9, 1-http/1.0, 2-http/1.1 *//* supported HTTP methods */#define Method_get 0#define method_head 1#define method_opt IONS 2#define method_trace 3#define program_version "1.5" int METHOD = Method_get; /* Default to get method */int clients = 1; /* Start a client (child process) by default */int force = 0; /* Whether to wait for response data to return, 0-wait, 1-no wait */int force_reload = 0; /* Whether to send Pragma:no-cache */int proxyport = 80; /* Proxy port */char *proxyhost = NULL; /* Proxy server name */int benchtime = 30; /* Execution time, when the child process execution time is over this number of seconds, send SIGALRM signal, set timerexpired to 1, let all child processes exit * * Pipeline, the child process to complete a request, the write end writes the data, the main process reads the data from the reading end */int Mypipe[2];char Host[maxhostnamelen]; /* Host name (64 bytes) */#define REQUEST_SIZE 2048char request[request_size];        /* Request string (HTTP header) *//* command-line option configuration table, man getopt_long */static const struct option long_options[] = {' force ', no_argument, &force, 1}, {"Reload", No_argument, &force_reload, 1}, {"Time", Required_argument, N          ULL, ' 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_a Rgument, &method, method_trace}, {"Version", No_argument, NULL, ' V '}, {"Proxy", req                 Uired_argument, NULL, ' P '}, {"Clients", required_argument, NULL, ' C '}, {null, 0, NULL, the 0}};/* child process performs the requested task of the function */static void Benchcore (const char* HOST,CONST int port, const char *request);/* Execute The main entry function of the */static int bench (void);/* generates an HTTP header */static void build_request (const char *url);/* Sets timerexpired to 1 so that all child processes Exit */static void Alarm_handler (int signal) {timerexpired=1;} /* Print help */static void usage (void) {fprintf (stderr, "webbench [option] ... Url\n ""-f|--force Don ' t wait for reply from server.\n ""-r|--reload Send rel Oad request-pragma:no-cache.\n ""-t|--time <sec> Run benchmark for <sec> seconds. DefauLt 30.\n ""-p|--proxy <server:port> use proxy server for request.\n ""-c|--clients <n> Run <n> HTTP clients at once. Default one.\n "" -9|--http09 use http/0.9 style requests.\n "" -1|--HTTP10 use http/1.0 protocol.\n "" -2|--http11 use http/1.1 protocol.\n ""--get use GET request Method.\n ""--head Use Head request method.\n ""--options U SE OPTIONS request method.\n ""--trace use trace request method.\n ""-?| -h|--help this information.\n "", "-v|--version Display program version.\n");    int main (int argc, char *argv[]) {int opt = 0;    int options_index = 0;    char *tmp = NULL;        if (argc = = 1) {usage ();    return 2; }/* parameter explanation, see Man Getopt_long * * while (opt = Getopt_long (argc, argv, "912vfrt:p:c:?h ", Long_options, &options_index))! = EOF) {switch (opt) {case 0:bre            Ak                Case ' f ': force = 1;            Break                 Case ' r ': force_reload = 1;             Break                Case ' 9 ': http10 = 0;            Break                Case ' 1 ': HTTP10 = 1;            Break                Case ' 2 ': HTTP10 = 2;            Break                Case ' V ': printf (program_version "\ n");            Exit (0);                Case ' t ': Benchtime = atoi (Optarg);                     Break                Case ' P ':/* Proxy Server parsing Server:port */tmp = STRRCHR (Optarg, ': ');                ProxyHost = Optarg;                if (tmp = = NULL) {break; } if (tmp = = Optarg) {fprintf (stderr, "Error in option--proxy%S:missing hostname.\n ", Optarg);                return 2; } if (tmp = = Optarg + strlen (optarg)-1) {fprintf (stderr, "Error in option--proxy%s P                    ORT number is missing.\n ", optarg);                return 2;                } *tmp= ' + ';                ProxyPort = atoi (tmp + 1);            Break                Case ': ': Case ' h ': Case '? ': usage ();                return 2;            Break                Case ' C ': Clients = atoi (OPTARG);        Break        }} if (Optind = = argc) {fprintf (stderr, "webbench:missing url!\n");        Usage ();    return 2;    } if (clients = = 0) {clients = 1;    } if (Benchtime = = 0) {benchtime = 60;  }/* Copyright * * fprintf (stderr, "Webbench-simple Web Benchmark" program_version "\ n" "Copyright (c)    Radim Kolar 1997-2004, GPL Open Source software.\n "); BUild_request (Argv[optind]);    /* The last non-option parameter is treated as a URL */* print Bench Info */printf ("\nbenchmarking:");            Switch (method) {case METHOD_GET:default:printf ("GET");        Break            Case method_options:printf ("OPTIONS");        Break            Case method_head:printf ("HEAD");        Break            Case method_trace:printf ("TRACE");    Break    } printf ("%s", Argv[optind]);            Switch (HTTP10) {Case 0:printf ("(using http/0.9)");        Break            Case 2:printf ("(using http/1.1)");    Break    } printf ("\ n");    if (clients = = 1) {printf ("1 Client");    } else {printf ("%d clients", clients);    } printf (", Running%d sec", benchtime);    if (force) {printf (", Early socket Close");    } if (ProxyHost! = NULL) {printf (", via Proxy server%s:%d", ProxyHost, ProxyPort); } if (force_reload) {printf (", forcing Reload ");    } printf (". \ n"); return Bench ();}    /* Generate HTTP Header */void build_request (const char *url) {char tmp[10];      int i;    Bzero (host, Maxhostnamelen);      Bzero (Request, request_size);    /* Protocol Adaptation * */if (force_reload && proxyhost! = NULL && Http10 < 1) {http10=1;    } if (method = = Method_head && Http10 < 1) {http10=1;    } if (method = = Method_options && Http10 < 2) {http10=2;    } if (method = = Method_trace && Http10 < 2) {http10=2;            } switch (method) {Default:case method_get:strcpy (request, "GET");        Break            Case method_head:strcpy (Request, "HEAD");        Break            Case method_options:strcpy (Request, "OPTIONS");        Break            Case method_trace:strcpy (Request, "TRACE");    Break      } strcat (Request, ""); if (NULL = = Strstr (URL, "://")) {fprintf (stderr, "\n%s:is not a valid url.\n", URL);    Exit (2);        } if (strlen (URL) >) {fprintf (stderr, "url is too long.\n");    Exit (2); } if (proxyhost = = NULL) {if (0! = strncasecmp ("http//", URL, 7)) {fprintf (stderr, "\nonly http Pro            Tocol is directly supported, set--proxy for others.\n ");        Exit (2);    }}/* Protocol/host delimiter */i = strstr (URL, "://")-url + 3; /* printf ("%d\n", I); */if (STRCHR (url + i, '/') = = NULL) {fprintf (stderr, "\ninvalid url syntax-hostname don ' t ends with '/'. \ n")        );    Exit (2); if (proxyhost = = NULL) {/* get port from hostname */if (index (URL + i, ': ')! = NULL && index (            URL + i, ': ') < index (URL + i, '/')} {strncpy (host, url + i, strchr (url + i, ': ')-url-i);            Bzero (TMP, 10); strncpy (TMP, index (URL + i, ': ') + 1, strchr (url + i, '/')-index (URL + i, ': ')-1);            /* printf ("tmp=%s\n", TMP);            */ProxyPort = atoi (TMP);            if (ProxyPort = = 0) {proxyport=80;        }} else {strncpy (host, url + i, strcspn (url + i, "/"));        }//printf ("host=%s\n", Host);    strcat (Request + strlen (request), url + i + strcspn (url + i, "/"));        } else {//printf ("proxyhost=%s\nproxyport=%d\n", Proxyhost,proxyport);    strcat (request, URL);    } if (http10 = = 1) {strcat (Request, "http/1.0");    } else if (HTTP10 = = 2) {strcat (Request, "http/1.1");    } strcat (Request, "\ r \ n");    if (Http10 > 0) {strcat (Request, "User-agent:webbench" program_version "\ r \ n");          } if (proxyhost = = NULL && http10 > 0) {strcat (Request, "Host:");          strcat (request, host);    strcat (Request, "\ r \ n");    } if (Force_reload && proxyhost! = NULL) {strcat (Request, "pragma:no-cache\r\n"); } if (Http10 &GT    1) {strcat (Request, "connection:close\r\n");     }/* Add empty line at end */if (Http10 > 0) {strcat (request, "\ r \ n"); }//printf ("req=%s\n", request);}        /* VRACI system RC error kod */static int bench (void) {int I, j, K;    pid_t pid = 0;      FILE *f;    /* Check avaibility of target server */i = Socket (ProxyHost = = NULL? host:proxyhost, ProxyPort); if (I < 0) {fprintf (stderr, "\nconnect to server failed.        Aborting benchmark.\n ");    return 1;    } close (i);        /* Create pipe */if (pipe (mypipe)) {perror ("pipe failed.");    return 3; }/* Not needed, since we had alarm () in childrens */* Wait 4 next system clock tick */* Cas=time (NULL)    ;    while (Time (NULL) ==cas) Sched_yield ();        */* Fork Childs */for (i = 0; i < clients; i++) {pid = fork (); if (PID <= (pid_t) 0) {/* child process or error*/sleep (1);/* Make ChilDS Faster */* This break is very important, it mainly allows the child process can only be generated from the parent process, otherwise the child process will generate the child process */break;        }} if (PID < (pid_t) 0) {fprintf (stderr, "problems forking worker No.%d\n", i);        Perror ("Fork failed.");    return 3; } if (pid = = (pid_t) 0) {/* I am a child */* sub-Process Execution request */if (proxyhost = = NULL) {Ben        Chcore (host, proxyport, request);        } else {Benchcore (proxyhost, proxyport, request);        }/* Write results to pipe */F = fdopen (Mypipe[1], "w");            if (f = = NULL) {perror ("Open pipe for writing failed.");        return 3; }/* fprintf (stderr, "child-%d%d\n", speed,failed);        */* Writes results to the pipeline */fprintf (f, "%d%d%d\n", speed, failed, bytes);        Fclose (f);    return 0;        } else {/* parent process reads the pipe, prints the result */printf ("Parent%d\n", Getpid ());        f = Fdopen (Mypipe[0], "R"); if (f = = NULL) {perror ("open pipe forReading failed. ");        return 3;        } setvbuf (f, NULL, _IONBF, 0);        Speed = 0;        Failed = 0;        bytes = 0;            while (1) {PID = fscanf (f, "%d%d%d", &i, &j, &k);                if (PID < 2) {fprintf (stderr, "Some of our childrens died.\n");            Break            } speed + = i;            Failed + = J;            bytes + = k; /* fprintf (stderr, "*knock*%d%d read=%d\n", speed,failed,pid);            */if (--clients = = 0) {break;        }} fclose (f); printf ("\nspeed=%d pages/min,%d bytes/sec.\nrequests:%d susceed,%d failed.\n", (int) ((speed + failed)/(b    enchtime/60.0f)), (int) (Bytes/(float) benchtime), speed, failed); } return i;}    void Benchcore (const char *host, const int port, const char *req) {int rlen;    Char buf[1500];    int s, I;     struct Sigaction sa;  /* This is the key, when the program executes to a specified number of seconds, send SIGALRM signal */sa.sa_handler = Alarm_handler;    sa.sa_flags = 0;    if (Sigaction (SIGALRM, &sa, NULL)) {exit (3);       } alarm (Benchtime);    Rlen = strlen (req);                 /* Unlimited execution of the request until timerexpired returns to 1 o'clock */nexttry:while (1) {if (timerexpired) {if (Failed > 0) { /* fprintf (stderr, "correcting failed by signal\n");            */failed--;        } return;                                  } s = Socket (host, Port);            if (s < 0) {failed++;        Continue            } if (Rlen! = Write (s, req, Rlen)) {failed++;            Close (s);        Continue } if (Http10 = = 0) {/* If it is http/0.9 then close the write operation of the socket */if (shutdown (s, 1)) {F                ailed++;                Close (s);            Continue }/* If you wait for the response data to return, read the response data, calculate the number of bytes transferred */if (force = = 0) {/* reaD all available data from Socket */while (1) {if (timerexpired) {break;                } i = Read (s, buf, 1500); /* fprintf (stderr, "%d\n", I);                    */if (I < 0) {failed++;                    Close (s);                Goto Nexttry;                    } else {if (i==0) {break;                    } else {bytes + = i;            }}}} if (Close (s)) {failed++;        Continue    }/* Successfully completed a request and counted */speed++; }}



Source Reading notes: webbench-1.5

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.