2010-10-15 6 views
0

J'ai développé un serveur (TCP) pour écouter un client et interagir avec lui. Maintenant j'essaye d'adapter ce code de serveur pour écouter des clients multiples. Je veux utiliser select, mais je suis confus avec certains des exemples et des explications que j'ai trouvés.en utilisant select() pour écouter plusieurs clients (TCP)

Je lis: http://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/select.htm et http://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/select.htm qui ont tous deux été recommandé pour moi ..: S

L'exemple du premier site semble moins complexe .. (mais ne savent toujours pas comment adapter à mon code car je suis très très nouveau sur le réseau, etc.) mais je m'inquiète de manquer des aspects clés en raison de la complexité de l'exemple du second site.

Ci-dessous est une sorte de cliché de mon code serveur lorsque écoute seulement un client (certains psuedocode inclus pour minimiser pas des choses importantes):

int main(int argc, char *argv[]) 
{ 
    int sockfd, newsockfd, portno, clilen; 
    char buffer[3]; 
    struct sockaddr_in serv_addr, cli_addr; 
    int n; 

    if (argc < 2) 
    { 
     fprintf(stderr,"ERROR, no port provided\n"); 
     exit(1); 
    } 

    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0){error("ERROR opening socket");} 

    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    portno     = atoi(argv[1]); 
    serv_addr.sin_family  = AF_INET; 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 
    serv_addr.sin_port  = htons(portno); 


    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
     {error("ERROR on binding");} 

    listen(sockfd,5); 

    clilen = sizeof(cli_addr); 
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 

    if (newsockfd < 0){error("ERROR on accept");} 


    while (UNTIL END OF FILE) 
    { 
     <DO SOME FILE READING STUFF> 

     n = write(newsockfd, "test/n", 5); 

     if (n < 0){error("ERROR writing to socket");} 


     bzero(buffer,3); 
     n = read(newsockfd,buffer,3); 

     if (n < 0){error("ERROR reading from socket");} 

     buffer[n] = 0; 

     <DO SOME STRING STUFF> 

     while(done != 1) 
     { 
      bzero(buffer,3); 
      n = read(newsockfd,buffer,3); 

      if (n < 0){error("ERROR reading from socket");} 

      buffer[n] = 0;  

      if(strcmp(buffer, "CO")) 
      { 
       done = 1; 
      } 
     } 

     done = 0; 
    } 

    <DO STUFF> 


    n = write(newsockfd, "DN\n", 2); 

    if (n < 0){error("ERROR writing to socket");} 

    close(sockfd); 
    close(newsockfd); 

    return 0; 

} 

exemple de Quel site pour select() fonctionnerait meilleur pour mon ce que je suis en train de faire (changer le code du serveur pour écouter plusieurs clients)? Quelqu'un pourrait-il expliquer select() en termes plus simples pour moi? (depuis que je suis si nouveau à ceci et tout ...)

Merci!

Répondre

7

Vous devez placer une boucle autour du accept() et du code suivant, de sorte que vous puissiez accepter plusieurs connexions pendant la durée de vie du programme. Vous devez ensuite décider comment votre serveur va gérer plusieurs connexions. Vous avez quelques choix:

  • Utilisez plusieurs threads, un thread par client.
  • Utilisez un serveur de forking, un processus par client.
  • Utilisez un serveur unique, qui utilisera select() pour décider quel (s) descripteur (s) de fichier est prêt (s).

Dans les deux premiers cas, le thread ou le processus enfant est occupé avec un seul client; il attendra pendant que le client travaille comment répondre à ce qu'il envoie, ce qui signifie que d'autres threads ou processus obtiennent un virage à la CPU. Il existe des variantes sur le thème qui permettent de lancer un certain nombre de threads ou de processus de travail et de faire en sorte que ceux-ci reprennent la charge de travail, mais c'est plus complexe. Dans le dernier cas, vous allez configurer un tableau des descripteurs de fichier sur lesquels vous souhaitez que select() fonctionne, puis transmettre une copie de cette liste à select() (car elle la piétine). Lorsque vous avez du travail à faire (car select() renvoie), vous effectuez un accept() sur le descripteur de fichier que vous écoutez si c'est prêt, ou vous lisez des descripteurs de socket déjà ouverts s'ils sont prêts.

Questions connexes