2016-09-08 11 views
0

select()機能を使用して複数のサーバーとの接続を確立できるクライアント機能を実装しようとしています。しかし、私はselect()機能を使用する専門家ではありません。 しかし、クライアントは複数のサーバーとの接続を有効にできますが、複数のサーバーからのメッセージを読み取ることができませんでした。ソケットクライアントを選択

次の例では、クライアントを2台のサーバー(192.168.100.136, 192.168.100.138)で接続しました。 は、これら二つのサーバに接続した後、私のクライアントではなく、複数のサーバからメッセージを受信する、唯一のサーバー(192.168.100.136)からメッセージを受信して​​いた。..

私は私のサンプルプログラムでselect()機能を使用方法についてはよく分かりません。 事前に おかげ

int main() 
{ 
    int port = 10001 ; 
    char ip[][32] = {"192.168.100.136","192.168.100.138"}; 
    int count = 2 ; 
    int ret = clientSelect(ip,port,count); 
    return 0 ; 
} 
int clientSelect(char **ipAddr ,int port , int count) 
    { 
    SOCKET max_sd = 0; 
    SOCKET socketId[10] = {0}; 
    SOCKET sd = 0 ; 
    SOCKET client_sock[1024] = {0} ; 
    fd_set readfds; 
    int i ,j , ret; 
    char recvBuf[1024] = ""; 
    char errMsg[256] = "" ; 
    struct sockaddr_in server ; 

    FD_ZERO(&readfds); 
    // Socket Initialization 
    for(i = 0; i<count ; i++) 
    { 
     ret = initSocket(&socketId[i]);//Small function to create socket 
     if (ret != 1) 
     { 
      return ret ; 
     } 
     //Server info 
     server.sin_addr.s_addr = inet_addr(ipAddr[i]); 
     server.sin_family  = AF_INET; 
     server.sin_port   = htons(port); 
     // Conect to server 
     if (connect(socketId[i], (struct sockaddr *)&server , sizeof(server)) < 0) 
     { 
      printf("connect ::Failed to connect to server %s:%d",ipAddr[i],port); 
      return -1; 
     } 
     // Set Socket fd 
     FD_SET(socketId[i], &readfds); 

     max_sd = (max_sd>socketId[i])?max_sd:socketId[i]; 
    } 
    while(TRUE) 
    { 
     ret = select(max_sd + 1, &readfds, NULL, NULL, NULL); 
     if (ret < 0) 
     { 
      printf("select failed\n "); 
      return -1; 
     } 
     for (j = 0 ; j<max_sd ; j++) 
     { 
      sd = client_sock[j] ; 
      if (FD_ISSET(sd, &readfds)) 
      { 
       ret = recv(sd,(char *)recvBuf,sizeof(recvBuf), 0); 
       if(ret > 0) 
       { 
        printf("Message received from socket %d : %s\n",sd,recvBuf); 
        send(sd,(char *)recvBuf,strlen(recvBuf),0); 
       } 
      } 
     } 
    } 

    return ret ; 

} 
+0

未定義の動作:

あなたのコードは次のようにする必要があります。あなたのコンパイラは、 'main'に' clientSelect'の宣言がないことについて文句を言います。 – Olaf

+1

無意味なスリープを取り除き、 'recv()'が0または-1を正しく返すケースを処理し、 'send()' -1を返す。そして 'strlen(recvBuf)'は 'ret'でなければなりません。あなたが実際に何を求めているのか不明です。 – EJP

+0

それはCかC++ですか?彼らは異なる言語です。一つを選ぶ! – Olaf

答えて

2

fd_setが各使用前に初期化する必要があります。...希望のO/Pを得るために、私のサンプルアプリケーションを修正してください

int clientSelect(char **ipAddr ,int port , int count) 
{ 
    SOCKET max_sd = 0; 
    SOCKET socketId[10] = {0}; 
    SOCKET sd = 0 ; 

    fd_set readfds; 
    int i ,j , ret; 
    char recvBuf[1024] = ""; 
    char errMsg[256] = "" ; 
    struct sockaddr_in server ; 

    // Socket Initialization 
    for(i = 0; i<count ; i++) 
    { 
     ret = initSocket(&socketId[i]);//Small function to create socket 
     if (ret != 1) 
     { 
      return ret ; 
     } 
     //Server info 
     server.sin_addr.s_addr = inet_addr(ipAddr[i]); 
     server.sin_family  = AF_INET; 
     server.sin_port   = htons(port); 
     // Conect to server 
     if (connect(socketId[i], (struct sockaddr *)&server , sizeof(server)) < 0) 
     { 
      printf("connect ::Failed to connect to server %s:%d",ipAddr[i],port); 
      return -1; 
     }  
    } 


    while(TRUE) 
    { 
     // init fd_set 
     FD_ZERO(&readfds); // added by siva to initialize socket descriptors 
     for(i = 0; i<count ; i++) 
     { 
      //FD_ZERO(&readfds); // Commented by siva to avoid initialization for each socket 
      FD_SET(socketId[i], &readfds); 
      max_sd = (max_sd>socketId[i])?max_sd:socketId[i]; 
     } 
     ret = select(max_sd + 1, &readfds, NULL, NULL, NULL); 
     if (ret < 0) 
     { 
      printf("select failed\n "); 
      return -1; 
     } 
     // warning: you don't know the max_sd value 
     for(i = 0; i<count ; i++) 
     { 
      sd = socketId[i] ; 
      if (FD_ISSET(sd, &readfds)) 
      { 
       ret = recv(sd,(char *)recvBuf,sizeof(recvBuf), 0); 
       if(ret > 0) 
       { 
        printf("Message received from socket %d : %s\n",sd,recvBuf); 
        send(sd,(char *)recvBuf,strlen(recvBuf),0); 
       } 
      } 
     } 
    } 

    return ret ; 

} 
+0

こんにちは、あなたの提案に従って機能を変更しました...しかし、私は両方のサーバーからのメッセージを受信するよりもむしろ1つのサーバーからメッセージを受け取っています....私は期待されるo/pを得るためにさらに私を案内してください..実際には私の要件は、サーバー&select()コンセプトを使用してメッセージのトランザクションを監視する...私の要件を満たすために私のサンプル関数で正しい方法で行っているかどうか、私を修正してください... @purplepsycho – Siva

+1

こんにちは@purplepsycho、私物事が期待どおりに正しく働いているあなたの答えに1つの小さな修正を行いました...私が修正で何か悪いことをしてください、私を修正してください。ありがとう – Siva

関連する問題