2010-10-15 59 views
0

我开发了(TCP)服务器来侦听客户端并与之交互。现在我试图调整这个服务器代码来收听多个客户端。我想要使​​用select,但是我对我发现的一些示例和解释感到困惑。使用select()来侦听多个客户端(TCP)

我一直在读:http://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/select.htmhttp://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/select.htm这两个国家都被推荐到我..:S

第一个站点的例子似乎不太复杂。(尽管仍然不知道如何将它适应我因为我对网络非常非常陌生等),但我担心由于第二个站点示例的复杂性,我错过了关键方面。

下面是那种我的服务器代码的快照时只监听一个客户端(包括一些伪代码,以尽量减少不那么重要的东西):

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; 

} 

哪个网站对选)为例(将工作最好为我我想要做的(更改服务器代码来听多个客户端)?有人可以用一些更简单的术语解释select()吗? (因为我对这个和所有这么新......)

谢谢!

回答

7

您需要围绕accept()和以下代码打包一个循环,以便您可以在程序的整个生命周期中接受多个连接。然后您需要确定您的服务器将如何处理多个连接。你有几个选择:

  • 使用多个线程,每个客户端一个线程。
  • 使用分叉服务器,每个客户端一个进程。
  • 使用一台服务器,它将使用select()来决定哪些文件描述符已准备就绪。

在前两种情况下,子线程或进程一心一意地处理一个客户端;它将等待客户端正在计划如何响应它发送的内容,这意味着其他线程或进程会在CPU上转向。这个主题有不同的版本,可以预先启动一些工作者线程或进程,并安排这些工作负载来承担工作量,但这更复杂。

在最后一种情况下,你会设置要select()工作的文件描述符的数组,然后通过该列表的副本select()(因为它践踏一切都结束吧)。当你有工作要做时(因为select()返回),如果已经准备就绪,你可以在正在监听的文件描述符上执行accept(),或者如果已准备就绪,可以从已打开的套接字描述符中读取。