📄 webmaster.c
字号:
int cnt,i;
/* DOESN'T ACTUALLY PRINT UNTIL THE FIRST CLIENT REPORTS */
fprintf(stdout,"Reading results ");
/*
* COPY THE FILE DESCRIPTORS TO A TMP LIST,
* ALLOCATE MEMORY FOR STATS, PAGESTATS IN TEXT FORM
*/
leftfdset = *fdset;
stats_as_text = (char *)mymalloc(SIZEOF_STATSTEXT+1);
page_stats_as_text = (char *)mymalloc(SIZEOF_PAGESTATSTEXT+1);
/*
* COPY THE FILE DESCRIPTORS TO A TMP LIST,
* PLUS A LIST OF REMAINING FDs
*/
leftfdset = *fdset;
/*
* LOOP UNTIL ALL CLIENTS HAVE REPORTED
* AND tmpfdset IS EMPTY
*/
#ifndef WIN32
while(memcmp(&leftfdset,&zerofdset,sizeof(fd_set)))
{
tmpfdset = leftfdset;
sleep(1);
returnval = select(FD_SETSIZE,&tmpfdset,NULL,NULL,NULL);
D_PRINTF( "Call to select returned %d, errno %d\n",
returnval, errno );
if(returnval < 0)
{
/*
* ERROR SELECTING. ABORT ALL.
*/
D_PRINTF( "select() error %s\n", neterrstr() );
abort_clients();
errexit("Error selecting from one of the clients\n");
}
#else
/* I don't see why a select is needed at all */
tmpfdset = leftfdset;
{
#endif /* WIN32 */
for(cnt = 0; cnt < totalnumclients; cnt++)
{
/*
* SEE WHICH SOCKETS HAVE A INPUT ON THEM PENDING AND
* RECEIVE IT.
*/
/* IS THIS A VALID SOCKET? IS IT READY TO READ? */
if(!BADSOCKET(socknum[cnt]) && (FD_ISSET(socknum[cnt],&tmpfdset)))
{
int len;
/*
* GET THE TIMING DATA FROM THIS GUY
* THEN REMOVE HIM FROM THE tmpfdset
*/
/*
* READ TIME STATS
* DOES READ() RETURN THE CORRECT LENGTH?
*/
D_PRINTF( "About to read timestats, count %d, errno %d\n",
cnt, errno );
len = SIZEOF_STATSTEXTBASE + number_of_pages*SIZEOF_DOUBLETEXT;
returnval = recvdata(socknum[cnt], stats_as_text,
len);
D_PRINTF( "Read time stats %d\n", returnval );
if (returnval != len) /* <= 0) */
{
D_PRINTF( "Error reading timing stats: %s\n",
neterrstr() );
fprintf(stderr, "Error reading timing stats: %s\nSocket number %d\n",
neterrstr(),socknum[cnt]);
abort_clients();
errexit("");
} /* end if */
/* convert text to stats */
stats_as_text[returnval] = 0; /* add an end marker */
statarray[cnt] = *text_to_stats(stats_as_text);
fputc('.', stdout); /* PROGRESS MARKER */
fflush(stdout);
if(uil_filelist_f) /* READ PAGE STATS */
{
for (i = 0; i < number_of_pages; i++)
{
D_PRINTF( "On page_stats[%d][%d]\n", cnt, i );
returnval = recvdata(socknum[cnt], page_stats_as_text,
SIZEOF_PAGESTATSTEXT);
D_PRINTF( "Read page stats %d\n", returnval );
if (returnval != SIZEOF_PAGESTATSTEXT) /* <= 0) */
{
D_PRINTF( "Error reading page_stats[%d][%d]: %s\n",
cnt, i, neterrstr() );
fprintf(stderr, "Error reading page_stats[%d][%d]: %s\n",
cnt, i, neterrstr());
abort_clients();
errexit("");
}
D_PRINTF( "Page stats: read %d bytes\n",
returnval );
page_stats_as_text[returnval] = 0; /* add an end marker */
D_PRINTF("strlen(page_stats_as_text) = %d\n",
strlen(page_stats_as_text));
page_stats[cnt][i] =
*text_to_page_stats(page_stats_as_text);
} /* end for */
} /* end if filelist */
FD_CLR(socknum[cnt],&leftfdset);
NETCLOSE(socknum[cnt]);
socknum[cnt] = BADSOCKET_VALUE;
} /* end if socknum */
} /* end for cnt */
} /* end while memcmp fd */
/*
* DONE READING RESULTS FROM CLIENTS
*/
*endtime = time(NULL);
timestr = asctime(localtime(endtime));
fprintf(stdout,"\nAll clients ended at %s\n",timestr);
fflush(stdout);
/* FREE MEMORY ALLOCATED FOR CLIENT STATS, PAGESTATS AS TEXT */
free(stats_as_text);
free(page_stats_as_text);
}
/*
Prints out all the results
*/
void PrintResults( page_stats, endtime, timestr, totalnumclients, statarray,
page_stats_total)
page_stats_t **page_stats;
time_t endtime;
char *timestr;
int totalnumclients;
stats_t statarray[MAXCLIENTS];
page_stats_t *page_stats_total;
{
stats_t masterstat;
int cnt,i,j;
double thruput;
struct timeval dtime;
/*
* PRINT EVERYTHING OUT
*/
stats_init(&masterstat);
for(cnt = 0; cnt < totalnumclients; cnt++)
{
if((statarray[cnt].rs.totalconnects > 0) && (dumpall))
{
fprintf(stdout,"----------------------------------\n");
/* fprintf(stdout,"Test for host: %s\n",statarray[cnt].hostname); */
fprintf(stdout,"Total number of pages retrieved from server: %u\n",
statarray[cnt].totalpages);
rqstat_fprint(stdout, &(statarray[cnt].rs));
thruput = thruputpersec((double)(statarray[cnt].rs.totalbytes),
&(statarray[cnt].rs.totalresponsetime));
fprintf(stdout, "Thruput average per connection: %.0f bytes/sec\n",
thruput);
}
if(statarray[cnt].rs.totalconnects > 0)
{
D_PRINTF( "Summing stats for %d, with %ld total connections\n",
cnt, statarray[cnt].rs.totalconnects );
rqstat_sum(&masterstat.rs, &(statarray[cnt].rs));
}
else
{
masterstat.rs.totalerrs += statarray[cnt].rs.totalerrs;
}
}
for (i=0; i < totalnumclients; i++)
{
for (j=0; j < number_of_pages; j++)
{
D_PRINTF( "Summing page stats for %d, page %d, with %d connects\n",
i, j, statarray[i].page_numbers[j] );
if (statarray[i].page_numbers[j] != 0)
{
rqst_stats_t *pst_rs;
rqst_stats_t *ps_rs;
pst_rs = &(page_stats_total[j].rs);
ps_rs = &(page_stats[i][j].rs);
rqstat_sum(pst_rs, ps_rs);
page_stats_total[j].totalpages += page_stats[i][j].totalpages;
masterstat.totalpages += page_stats[i][j].totalpages;
/* yes, this is assignment, not sum */
page_stats_total[j].page_size = page_stats[i][j].page_size;
page_stats_total[j].page_valid = 1;
}
}
}
/* print page statistics */
if (verbose) {
for (i = 0; i < number_of_pages; i++)
{
if (page_stats_total[i].page_valid == 1)
{
page_stats_t *pst;
pst = &(page_stats_total[i]);
printf ("===============================================================================\n");
printf ("Page # %d\n\n", i);
printf ("Total number of times page was hit %u\n",
pst->totalpages);
rqstat_print(&(pst->rs));
printf ("Page size %u \n", pst->page_size);
printf ("===============================================================================\n\n");
}
}
}
fprintf(stdout,"===============================================================================\n");
/*
* Validate run.
*/
masterstat.total_num_of_files = statarray[0].total_num_of_files;
for (i=1; i < totalnumclients; i++)
{
if ((statarray[i].rs.totalconnects > 0) &&
(statarray[i].total_num_of_files != masterstat.total_num_of_files))
{
fprintf(stdout,"**********************************************************************\n");
fprintf(stdout,"**** ERROR: number of files in each test configuration is not the same\n");
fprintf(stdout,"**** ERROR: Check configuration file %s on each client\n", configfile);
fprintf(stdout,"**********************************************************************\n");
break;
}
}
/*
* Print summary statistics
*/
fprintf(stdout, "WEBSTONE 2.0 results:\n");
fprintf(stdout, "Total number of clients: \t%d\n", totalnumclients);
testtime = sumedh_end.tv_sec - sumedh_start.tv_sec;
fprintf(stdout,"Test time: \t\t\t%d seconds\n", testtime);
fprintf(stdout, "Server connection rate: \t%3.2f connections/sec\n",
(double)(masterstat.rs.totalconnects)/(testtime));
fprintf(stdout, "Server error rate: \t\t%4.4f err/sec\n",
(double)(masterstat.rs.totalerrs)/(testtime));
fprintf(stdout, "Server thruput: \t\t%2.2f Mbit/sec\n",
(double)(8*masterstat.rs.totalbytes)/(testtime*1024*1024));
fprintf(stdout, "Little's Load Factor: \t\t%3.2f \n",
(double)(masterstat.rs.totalresponsetime.tv_sec)
/(testtime));
avgtime(&masterstat.rs.totalresponsetime,
masterstat.rs.totalconnects, &dtime);
fprintf(stdout, "Average response time: \t\t%4.4f millisec\n",
(double)1000*(dtime.tv_sec + (double)dtime.tv_usec / 1000000));
fprintf(stdout, "Error Level:\t\t\t%4.4f %%\n",
(double)(100 * masterstat.rs.totalerrs)/(masterstat.rs.totalconnects));
/* so much for the key metrics */
thruput = 8 * thruputpersec((double)(masterstat.rs.totalbytes),
&(masterstat.rs.totalresponsetime));
fprintf(stdout, "Average client thruput: \t%4.4f Mbit/sec\n",
thruput/(1024*1024));
fprintf(stdout,"Sum of client response times:\t%u.%u sec\n",
masterstat.rs.totalresponsetime.tv_sec,
masterstat.rs.totalresponsetime.tv_usec);
fprintf(stdout,"Total number of pages read:\t%u\n\n",
masterstat.totalpages);
/* Remaining stats are the same as usual */
rqstat_fprint(stdout, &(masterstat.rs));
fflush(stdout);
}
#ifdef WIN32
/* close socket library */
void sock_cleanup(void) {
WSACleanup();
}
#endif /* WIN32 */
void
main(const int argc, char *argv[])
{
int sync_sock;
int i;
int j;
char buffer[NCCARGS];
char commandline[NCCARGS];
char *timestr;
time_t starttime;
time_t endtime;
fd_set fdset;
/* make the big arrays static to avoid stack overflow */
static char clienthostname[MAXCLIENTS][MAXHOSTNAMELEN];
static stats_t statarray[MAXCLIENTS];
page_stats_t **page_stats;
page_stats_t *page_stats_total;
struct sockaddr_in serveraddr;
#ifdef WIN32
WSADATA WSAData;
COORD dwSize;
if ((WSAStartup(MAKEWORD(1,1), &WSAData)) != 0) {
errexit("Error in WSAStartup()\n");
}
atexit(sock_cleanup);
/* increase size of output window */
dwSize.X = 80;
dwSize.Y = 500;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), dwSize);
#endif /* WIN32 */
/* Initalization of variables. */
debugfile = stdout;
memset(buffer, 0, NCCARGS);
memset(webserver, 0, MAXHOSTNAMELEN);
memset(configfile, 0, MAXPATHLEN);
FD_ZERO(&zerofdset);
FD_ZERO(&fdset);
for(i = 0; i < MAXCLIENTS; i++)
{
socknum[i] = BADSOCKET_VALUE;
statarray[i].rs.totalconnects = 0;
}
signal(SIGINT, sig_int);
ParseCmdLine( argc, argv);
sync_sock = SetupSyncSocket( &serveraddr );
MakeCmdLine( commandline);
totalnumclients = RexecClients( commandline, clienthostname, &serveraddr);
/* Initalization of variables. */
page_stats =
(page_stats_t **)
mymalloc(totalnumclients*sizeof(page_stats_t *));
for (i=0; i < totalnumclients; i++)
{
page_stats[i] = (page_stats_t *)
mymalloc(number_of_pages*sizeof(page_stats_t));
}
page_stats_total =
(page_stats_t *)mymalloc(number_of_pages*sizeof(page_stats_t));
for (i=0; i < totalnumclients; i++) {
stats_init(&(statarray[i]));
}
for (i=0; i < totalnumclients; i++) {
for (j=0; j < number_of_pages; j++) {
page_stats_init(&(page_stats[i][j]));
}
}
for (i=0; i < number_of_pages; i++) {
page_stats_init(&(page_stats_total[i]));
}
for(i = 0; i < totalnumclients; i++)
{
socknum[i] = BADSOCKET_VALUE;
statarray[i].rs.totalconnects = 0;
}
GetReady( &fdset, totalnumclients, sync_sock );
NETCLOSE(sync_sock);
/*
* START ALL OF THE CLIENTS BY SENDING THEM A GO SIGNAL.
*/
gettimeofday (&sumedh_start, NULL);
SendGo( totalnumclients, socknum);
/*
* WAIT FOR ALL OF THE CLIENTS TO COMPLETE. WE SHOULD GET A REPLY
* FOR EACH SOCKET WE HAVE OPEN. THE REPLY WILL BE THE TIMING
* INFORMATION WE USE.
*/
starttime = time(NULL);
timestr = asctime(localtime(&starttime));
fprintf(stdout,"All clients started at %s\n",timestr);
fprintf(stdout,"Waiting for clients completion\n");
fflush(stdout);
/* IF THIS IS A TIMED TEST, WE MIGHT AS WELL SNOOZE */
if (testtime) {
sleep(testtime * 60);
}
GetResults( &fdset, page_stats, &endtime, timestr, totalnumclients,
statarray);
gettimeofday (&sumedh_end, NULL);
PrintResults( page_stats, endtime, timestr, totalnumclients, statarray,
page_stats_total);
/* free memory */
for (i = 0; i < totalnumclients; i++)
{
free(page_stats[i]);
}
free(page_stats);
free(page_stats_total);
exit(0);
}
/* Added by Rajesh Shah 5/18/96 */
void
HostEntCpy(struct hostent *dest, struct hostent *src)
{
dest->h_name = (char *)malloc(strlen(src->h_name)+1);
strcpy(dest->h_name, src->h_name);
printf("WebMaster name = %s\n", dest->h_name);
dest->h_aliases = src->h_aliases;
dest->h_addrtype = src->h_addrtype;
dest->h_length = src->h_length;
dest->h_addr_list = src->h_addr_list;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -