⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webmaster.c

📁 最新的版本ACE-5.6.8,刚从外文网上搬下,与大家分享.
💻 C
📖 第 1 页 / 共 3 页
字号:
struct sockaddr_in *serveraddr;
{
  int sock,len;

    /*
     * SET UP THE SOCKET WE ARE GOING TO USE TO SYNCHRONIZE WITH THE CLIENTS.
     */
    D_PRINTF( "About to call sock %d %d\n", portnum, MAXCLIENTS );

    sock = passivesock(0, "tcp", MAXCLIENTS);

    if (BADSOCKET(sock))
    {
        errexit("Couldn't open socket %d: %s\n", sock, neterrstr());
    }
  D_PRINTF( "The passivesock call succeeded\n" );

    D_PRINTF( "calling getsockname\n" );

    len = sizeof(struct sockaddr);  
    if(getsockname(sock, (struct sockaddr *)serveraddr, &len) < 0)
    {
  errexit("Could not get socket informaton\n");
    }
  
  return( sock );
}

/*
  Function which generates a commandline for the webclients
*/
void MakeCmdLine( commandline)
char *commandline;
{
    char tmpcommandline[NCCARGS];
    char hostname[MAXHOSTNAMELEN];
    char *webclient_path, *temp;
    int  cnt;
    struct hostent  *master_phe_tmp; /* temp. variable added by - Rajesh Shah*/

    /*
     * BUILD THE PORTIONS OF THE cmdline FOR EACH CLIENT THAT WE CAN BUILD NOW.
     * WE WILL FILL IN THE NUMBER OF CLIENTS LATER WITH AN sprintf.
     */
    D_PRINTF( "Calling gethostname\n" );

    if(gethostname(hostname,MAXHOSTNAMELEN) != 0)
    {
  errexit("Could not retrieve local host name");
    } else {
  /* convert hostname to address (to avoid DNS problems for webclients) */
  /* The following lines are add to copy the system 
     buffer (output of gethostbyname()) into user area.
           This is because, there are very good chances that later
     on system buffer might be overwritten by some calls and
     still if your pointer is pointing to same addr. nothing
     but only trouble and trouble! Infact this is what 
           happening when I tried to run webstone benchmark for more
           then one clients. It used to over write the webmaster name
     with the first client name and so remaining on client(s)
     the webclient process(es) were invoked with wrong webmaster
     name! This behaviour is observed Solaris 2.4 this bug 
     can be hit in any OS.    - Rajesh Shah 5/18/96 */
       
  /* master_phe = gethostbyname(hostname); */
  master_phe_tmp = gethostbyname(hostname); 
  master_phe = (struct hostent *)malloc(sizeof(struct hostent));
  HostEntCpy(master_phe, master_phe_tmp);
    }

    /* set up executable pathname */
#ifndef WIN32
    temp = getenv("TMPDIR");

    if ( temp && *temp ) {
      webclient_path = (char *)mymalloc( strlen(temp) + strlen("/webclient")
              + 1);
      strcpy(webclient_path, temp);
      strcat(webclient_path, "/webclient");
      
    } else
#else
    temp = temp;
#endif /* WIN32 */
      webclient_path = PROGPATH;


    D_PRINTF( "Path to webclient is: %s\n", webclient_path );

    sprintf(commandline,"%s", webclient_path);

    if(haveproxyserver)
    {
        sprintf(tmpcommandline, " -P %s", proxyserver);
        strcat(commandline, tmpcommandline);
    }
    if (debug)
    {
       strcat(commandline," -d");
    }
    if (numloops != 0)
    {
        sprintf(tmpcommandline," -l %d", numloops);
        strcat(commandline,tmpcommandline);
    }
    if (portnum)
    {
        sprintf(tmpcommandline," -p %d", portnum);
        strcat(commandline,tmpcommandline);
    }
    if (redirect)
    {
        strcat(commandline," -r");
    }
    if (savefile)
    {
        strcat(commandline," -s");
    }
    if (uil_filelist_f)
    {
        strcat(commandline," -u ");
  strcat(commandline,uil_filelist);
    }
    if (record_all_transactions)
    {
  strcat(commandline," -R");
    }
    if (testtime != 0)
    {
        sprintf(tmpcommandline," -t %d", testtime);
        strcat(commandline,tmpcommandline);
    }

    /*
     * SET UP A SPACE FOR THE NUMBER OF CLIENTS ON THE commandline.
     */
    sprintf(tmpcommandline,"%s -n %%d -w %%s -c %%s:%%d", commandline);
    strcpy(commandline,tmpcommandline);
    
    if (uil_filelist_f == 0)
    {
  cnt = 0;
  while(cnt < number_of_pages)
  {
     /*
      * PUT THE FILES AT THE END OF THE LIST.
      */
      strcat(commandline," ");
      strcat(commandline,filelist[cnt]);
      cnt++;
  }
    }
    puts(commandline);
}

/*
  rexec to the client hosts and start the webclients
*/
int RexecClients( commandline, clienthostname, serveraddr)
char *commandline;
char  clienthostname[MAXCLIENTS][MAXHOSTNAMELEN];
struct sockaddr_in  *serveraddr;

{
  int   tmpfd;
  int   numclients = 0;
  char    tmpcommandline[NCCARGS];
  struct servent *inetport;
  int   cnt;
  char    buffer[NCCARGS];
  char    login[MAXUSERNAME];
  char    password[MAXPASSWD];
  FILE    *fp;
  int   returnval;
  char    *tmphostname;

  memset(buffer, 0, sizeof(buffer));

    /*
     * OPEN UP THE CONFIG FILE. FOR EACH LINE IN THE CONFIG FILE, CHECK
     * ITS VALIDITY AND THEN rexec A COMMAND ON THE CLIENT.
     */

    if ((fp = fopen(configfile,"r")) == 0)
    {
        errexit("Could not open config file %s\n", configfile);
    }
   
    if ((inetport = getservbyname("exec","tcp")) == 0)
    {
        errexit("Could not get service name for exec/tcp\n");
    }
    D_PRINTF( "getservbyname returned %d\n", ntohs(inetport->s_port) );
    
    cnt = 0;

    D_PRINTF( "rexec loop\n" );
    while(1)
    {
  char webserver2[MAXHOSTNAMELEN];
  char linebuf[150];
  int num;
  char *primename;

  if (0 == fgets(linebuf, sizeof(linebuf), fp))
      break;
  num = sscanf(linebuf,"%s %s %s %d %s",clienthostname[cnt],login,password,
              &numclients, webserver2);
  if (num < 4)
      break;
  if (servaddrin_config) {
      if (num == 4) {
    errexit("No webserver specified in config file for %s\n", clienthostname[cnt]);
      }
      strcpy(webserver, webserver2);
  }

  if (numclients <= 0)
      errexit("Number of clients must be >= 0\n");
  if (numclients > MAXPROCSPERNODE)
  {
      errexit("Number of clients per node can't exceed %d\n", MAXPROCSPERNODE);
  }
        totalnumclients += numclients;

  primename = pick_webmaster_IP_address(clienthostname[cnt], master_phe, network_mask);
  if (primename == 0) {
      errexit("Bad client address %s for Client %d\n", clienthostname[cnt], cnt); 
  }

        fprintf(stdout,"Client %d: %s \t# Processes: %d\n    Webserver: %s\tWebmaster: %s:%d\n",
    cnt, clienthostname[cnt], numclients, webserver, primename,
    ntohs(serveraddr->sin_port));
  fflush(stdout);
        sprintf(tmpcommandline, commandline, numclients, webserver, primename,
      ntohs(serveraddr->sin_port));

        fprintf(stderr, "tmpcommandline: %s\n", tmpcommandline);

  D_PRINTF( "%s rexec %s\n",&clienthostname[cnt],tmpcommandline );
  if (norexec) {
      sleep(30);  /* gives some time to start clients for debugging */
  } else {

      tmphostname = &(clienthostname[cnt][0]);
      tmpfd = rexec(&tmphostname, inetport->s_port, login, password,
            tmpcommandline, &sockErr[cnt]);
      if((sockIO[cnt] = tmpfd) < 0)
      {
    errexit("Could not rexec: rexec to client %s, cmdline %s failed\n",
      clienthostname[cnt],tmpcommandline);
      }
  }
      

  returnval = NETREAD(tmpfd, buffer, OKSTRLEN);
  D_PRINTF( "read returns %d, %s\n", returnval, buffer );

  if (returnval <= 0 || memcmp(buffer, OKSTR, OKSTRLEN) != 0)
  {
          errexit("rexec to client %s, cmdline %s received error %s\n",
      clienthostname[cnt],tmpcommandline, buffer);
  }


  cnt++;
  if (cnt > MAXCLIENTS || cnt > FD_SETSIZE)
  {
      errexit("Number of Clients can't exceed %d\n", MAXCLIENTS);
  }
    }

    num_rexecs = cnt;
    if (totalnumclients > MAXTOTALPROCS)
    {
        errexit("Total number of processes can't exceed  %d\n",
    MAXTOTALPROCS);
    }

#ifndef WIN32
      /* NOW WE NEED TO HANDLE THE OUTPUT FROM THE REXEC.
       * TO DO THIS, WE FORK, THEN HAVE ONE PROCESS READ FROM TMPFD.
       * THE OTHER PROCESS CONTINUES WITH THE PROGRAM
       */
      D_PRINTF( "Forking webclient stderr/stdout processes\n" );
      switch (fork()) 
  { 
  case -1:   /* ERROR */
    errexit("fork: %s\n", strerror(errno));
  case 0:    /* CHILD */
    exit(echo_client(clienthostname[cnt], tmpfd)); 
  default:   /* PARENT */
    break;
  } 
#else
    /* start threads to echo stdout/stderr from clients */
    _beginthread(echo_client, 0, (void *)0);
    _beginthread(echo_client, 0, (void *)1);
#endif /* WIN32 */

    fprintf(stdout,"\n");
    fprintf(stdout,"\n");
    fclose(fp);

    return totalnumclients;
}

void GetReady( fdset, totalnumclients, sock )
fd_set *fdset;
int totalnumclients;
int sock;
{
  int cnt,len;
  fd_set tmpfdset, leftfdset;
  char  buffer[NCCARGS];

    /*
     * NOW WE NEED TO ACCEPT ALL THE CONNECTIONS FROM THE CLIENTS,
     * ACCEPT ALL THE READY MESSAGES
     */

    D_PRINTF( "Beginning accept loop\n" );
    for (cnt = 0; cnt < totalnumclients; cnt++)
    {
  D_PRINTF( "Client %d:\t", cnt );

  {
      fd_set readfds;
      struct timeval timeout;
      int rv;

      timeout.tv_sec = MAX_ACCEPT_SECS;
      timeout.tv_usec = 0;
      FD_ZERO(&readfds);
      FD_SET(sock, &readfds);

      /* if we're hung, quit */
      D_PRINTF("Before select() on listen() socket\n");
      if (!(rv = select(FD_SETSIZE, &readfds, 0, 0, &timeout)))  {
    fprintf(stdout,
        "Listen timeout after %d seconds (%d clients so far)\n",
        MAX_ACCEPT_SECS, cnt);
    D_PRINTF("select() timed out after %d seconds\n", MAX_ACCEPT_SECS);
    errexit("Webmaster terminating\n");
      }
  }

        if(BADSOCKET(socknum[cnt] = accept(sock, 0, 0)))
        {
            /*
             * ERROR accepting FROM THE CLIENTS. WE NEED TO ISSUE AN
             * ABORT TO ALL.
             */
            abort_clients();
            errexit("Error accepting from one of the clients: %s", neterrstr());
        } else
        {
            /*
             * SET THE FD IN THE MASK
             */
            FD_SET(socknum[cnt],fdset); 
        }
  D_PRINTF( "on socket %d\n",socknum[cnt] );
    }
    D_PRINTF( "\n" );

    /*
     * WAIT FOR A READY.
     */
    sleep(1);
    fprintf(stdout,"Waiting for READY from %d clients\n",totalnumclients);
    fflush(stdout);
    leftfdset = *fdset;
#ifndef WIN32
    while(memcmp(&leftfdset,&zerofdset,sizeof(fd_set)))
    {
        tmpfdset = leftfdset;

        if(select(FD_SETSIZE,&tmpfdset,NULL,NULL,NULL) < 0)
        {
            /*
             * ERROR SELECTING. ABORT ALL.
             */
            abort_clients();
            errexit("Error accepting from one of the clients: %s\n",
      neterrstr());
            break;
        }
#else
    /* I don't see why a select is needed at all--all clients must respond
     * and there is no synchronization/timing issue.
     */
    tmpfdset = leftfdset;
    {
#endif /* WIN32 */

        for (cnt = 0; cnt < totalnumclients; cnt++)
        {
            /*
             * SEE WHICH SOCKETS HAVE A INPUT ON THEM PENDING
             * AND RECEIVE IT.
             */
            if(!BADSOCKET(socknum[cnt]) && (FD_ISSET(socknum[cnt],&tmpfdset)))
            {
                /*
                 * GET THE READY FROM THIS GUY. 
                 * DON'T FORGET TO CLEAR HIS BIT IN THE tmpfdset
                 */
    len = NETREAD(socknum[cnt],buffer,READYSTRLEN);
                if(len != READYSTRLEN)
                {
                     abort_clients();
                     errexit("Error reading from client #%d\n", cnt);
                }
                if(memcmp(buffer, READYSTR, READYSTRLEN))
          {
                     abort_clients();
                     fprintf(stdout,"Received bad READY string: len %d, value %s\n",
            len,buffer);
                }
                FD_CLR(socknum[cnt],&leftfdset);
            }
        }
    }
    sleep(1);
    fprintf(stdout,"All READYs received\n");
    fflush(stdout);  
}

/*
  Start all the clients by sending them a GO signal
  totalnumclients is the total number of clients
  socknum is an int array with the filedescriptors for all the
     client connections
*/
void SendGo( totalnumclients, socknum)
int totalnumclients;
int *socknum;
{
  int cnt;
  fprintf(stdout,"Sending GO to all clients\n");
  for(cnt = 0; cnt < totalnumclients; cnt++)
    {
      if(socknum[cnt] > 0)
        {
    /*
     * SEND A GO 
     */
    if(NETWRITE(socknum[cnt], GOSTR, GOSTRLEN) != GOSTRLEN)
            {
        abort_clients();
        errexit("Error sending GO to client %d: %s\n", cnt, neterrstr());
            }
        }
    }
}

/*
  This function gathers statistics from all the clients
*/

void GetResults(fdset, page_stats, endtime, timestr, totalnumclients,
    statarray)
fd_set *fdset;
page_stats_t **page_stats;
time_t *endtime;
char *timestr;
int totalnumclients;
stats_t statarray[MAXCLIENTS];
{
  fd_set leftfdset,tmpfdset;
  char *stats_as_text;
  char *page_stats_as_text;
  int returnval;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -