2017-02-10 75 views
3

我使用select()編寫服務器程序。在這個程序中,我可以連接多個客戶端。但是這臺服務器只與最新的客戶端通話。我找不到問題。請幫助我。對於客戶端程序,我使用telnet命令(telnet 192.168.100.143 8181)。c(TCP)中的單個服務器程序的多個客戶端

SERVER.C

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <arpa/inet.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 


#define SERVER_IP  "192.168.100.143" 
#define CLIENT_IP  "192.168.100.5" 
#define PORT   8181 

#define BUF_LEN   256 

fd_set read_fd; 
int32_t server_id, client_id, fdmax, ret, client_no; 
struct sockaddr_in server, client; 

int main() 
{ 
     int32_t opt=1; 
     socklen_t len; 
     char IP[INET_ADDRSTRLEN],buffer[BUF_LEN]; 

     if((server_id=socket(AF_INET,SOCK_STREAM,0))==-1) { 
     perror("Unable to create Server ocket"); 
     exit(-1); 
    } 

    if(setsockopt(server_id, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) { 
       perror("setsockopt error..."); 
       exit(-1); 
     } 

     memset((char *) &server,0, sizeof(server)); 
    server.sin_family=AF_INET; 
    server.sin_port=htons(PORT); 
     inet_pton(AF_INET, SERVER_IP , &server.sin_addr); 
    bzero(&server.sin_zero,8); 

    if((bind(server_id,(struct sockaddr*)&server,sizeof(struct sockaddr_in)))==-1) { 
     perror("Unable to bind the server address..."); 
     exit(-1); 
    } 

    listen(server_id,5); 
    printf("\nWaiting for connection\n"); 

     FD_ZERO(&read_fd); 
    FD_SET(server_id,&read_fd); 

    fdmax=server_id; 

     while(1){ 

       printf("%d\n",__LINE__); 
       printf("fdmax = %d \n",fdmax); 
       if((select(fdmax+1,&read_fd,NULL,NULL,NULL)) <0) { 
         perror("Select\n"); 
         return -1; 
       } 
       printf("%d\n",__LINE__); 

       if(FD_ISSET(server_id,&read_fd)) { 
         if((client_id=accept(server_id,(struct sockaddr*)&client,&len))==-1) { 
         perror("Cannot accept the client..."); 
         exit(-1); 
         } 
         printf("New client %d connectd \n",client_id); 
         FD_SET(client_id, &read_fd); 
         fdmax = client_id; 
       } else { 
         for(client_no = server_id+1; client_no <=fdmax; client_no++) { 
           if(FD_ISSET(client_no, &read_fd)) { 
             printf("%d\n",__LINE__); 
             ret = recv(client_no, buffer, BUF_LEN, 0); 
             if(ret == 0) { 
               printf("client %d disconnectd \n",client_no); 
               FD_CLR(client_no, &read_fd); 
               close(client_no); 
               break; 
             } else { 
               printf("Received from client %d = %s \n",client_no,buffer); 
             } 
           } 
         } 
       } 
     } 
     close(client_id); 
     close(server_id); 
     return 0; 
} 

回答

1

你需要調用FD_SET上的while(1)每次迭代所有文件描述符(包括監聽FD)。

在您的代碼中server_id沒有設置在while(1)循環內。因此,一旦第一個客戶端連接併發送數據,就不會通知新的套接字連接和數據。

while(1) 
{ 
    FD_SET(server_id,&read_fd); //This should work. 
... 
}