2016-12-10 23 views
0

ソケットを使用してCでチャットプログラムを書く必要があり、途中で立ち往生しました。C言語 - ソケット - 2人のクライアント間のチャット(中間の人として1台のサーバーを使用)

私は、server、client1、client2の3つのファイルを持っています。私の当初の計画: - クライアント1が

  • Serverはそれを受け取り、クライアント2
  • に送信
  • をクライアント2が
  • Serverは、クライアント2のメッセージを受信し、クライアント1のメッセージを受信し、バックに何かを書き込み、それをサーバーに送信し、サーバーにメッセージを送信クライアント1に送信します。
  • クライアント1はそれを受け取り、最初にサーバーなどで受け取った何かを書きます.etetetc。

いずれかのクライアントが「終了」を送信するとループが終了します。いくつかの単語で

私の問題は: - クライアント2は、クライアント1にその最初のメッセージを送信した後、

  • しかし(クライアント1に>クライアント2は、クライアント2はClient1)

    • 最初の交換が成功します、彼はClient1の応答を待つことはありません。彼は "Client1:"とメッセージの空行を書いて、すぐに自分の "Client2:"メッセージフィールドを開きます。

    ここで神の名前に間違いがありますか?

    Client1.c

    #include <stdio.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <string.h> 
    
    int compare_strings(char a[], char b[]) 
    { 
        int c = 0; 
        while (a[c] == b[c]) 
        { 
         if (a[c] == '\0' || b[c] == '\0') 
         break; 
         c++; 
        } 
        if (a[c] == '\0' && b[c] == '\0') 
        return 0; 
        else 
        return -1; 
    } 
    
    
    int main() { 
        int clientSocket; 
        char buffer[1024]; 
        struct sockaddr_in serverAddr; 
        socklen_t addr_size; 
        int cmdEXIT = 0; 
    
        clientSocket = socket(PF_INET, SOCK_STREAM, 0); 
    
        serverAddr.sin_family = AF_INET; 
        serverAddr.sin_port = htons(7891); 
        serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
        memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 
    
        addr_size = sizeof serverAddr; 
        connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); 
    
        while (cmdEXIT == 0) 
        { 
         printf("Client 1 : "); 
         scanf(" %[^\n]s", buffer); 
         send(clientSocket,buffer,sizeof buffer - 1,0); 
         if (compare_strings(buffer, "exit")==-1) 
         { 
    
          memset(&buffer[0], 0, sizeof(buffer)); 
    
          recv(clientSocket, buffer, sizeof buffer - 1, 0); 
          if (compare_strings(buffer, "exit")==-1) 
          { 
           printf("Client 2 : "); 
           printf("%s\n", buffer); 
           memset(&buffer[0], 0, sizeof(buffer)); 
          } 
          else cmdEXIT=1; 
         } 
         else cmdEXIT=1; 
        } 
        return 0; 
    } 
    

    Server.c

    #include <stdio.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <string.h> 
    
    int compare_strings(char a[], char b[]) 
    { 
        int c = 0; 
        while (a[c] == b[c]) 
        { 
         if (a[c] == '\0' || b[c] == '\0') 
         break; 
         c++; 
        } 
        if (a[c] == '\0' && b[c] == '\0') 
        return 0; 
        else 
        return -1; 
    } 
    
    int main() { 
        int welcomeSocket, newSocket, Client2; 
        struct sockaddr_in serverAddr; 
        struct sockaddr_storage serverStorage; 
        socklen_t addr_size; 
    
        char buffer[1024]; 
    
        welcomeSocket = socket(PF_INET, SOCK_STREAM, 0); 
    
        serverAddr.sin_family = AF_INET; 
        serverAddr.sin_port = htons(7891); 
        serverAddr.sin_addr.s_addr = inet_addr("127.0.01"); 
        memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 
    
        bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); 
    
        if (listen(welcomeSocket,5)==0) 
         printf("Listening\n"); 
        else 
         printf("Error\n"); 
    
        addr_size = sizeof serverStorage; 
        newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size); 
        Client2 = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size); 
    
        int cmdEXIT = 0; 
    
        while (cmdEXIT == 0) 
        { 
         recv(newSocket, buffer, 1024, 0); 
         printf ("%s\nEnvoie au Client2\n", buffer); 
         send(Client2,buffer,1024,0); 
         if (compare_strings(buffer, "exit")==0) 
         { 
          cmdEXIT = 1; 
         } 
         else 
         { 
          memset(&buffer[0], 0, sizeof(buffer)); 
          recv(Client2, buffer, 1024, 0); 
          printf ("%s\nEnvoie au Client1\n", buffer); 
          send(newSocket,buffer,1024,0); 
          if (compare_strings(buffer, "exit")==0) 
          { 
           cmdEXIT = 1; 
          } 
         } 
        } 
    
        return 0; 
    } 
    

    Client2.c

    #include <stdio.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <string.h> 
    
    int compare_strings(char a[], char b[]) 
    { 
        int c = 0; 
        while (a[c] == b[c]) 
        { 
         if (a[c] == '\0' || b[c] == '\0') 
         break; 
         c++; 
        } 
        if (a[c] == '\0' && b[c] == '\0') 
        return 0; 
        else 
        return -1; 
    } 
    
    int main() { 
        int clientSocket; 
        char buffer[1024]; 
        struct sockaddr_in serverAddr; 
        socklen_t addr_size; 
        int cmdEXIT = 0; 
    
        clientSocket = socket(PF_INET, SOCK_STREAM, 0); 
    
        serverAddr.sin_family = AF_INET; 
        serverAddr.sin_port = htons(7891); 
        serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
        memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 
    
        addr_size = sizeof serverAddr; 
        connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); 
    
    
        while (cmdEXIT == 0) 
        { 
         recv(clientSocket, buffer, sizeof buffer - 1, 0); 
         if (compare_strings(buffer, "exit")==-1) 
         { 
          printf("Client 1 : "); 
          printf("%s\n", buffer); 
          memset(&buffer[0], 0, sizeof(buffer)); 
    
          printf("Client 2 : "); 
          scanf(" %[^\n]s", buffer); 
          send(clientSocket,buffer,sizeof buffer - 1,0); 
          if (compare_strings(buffer, "exit")==-1) 
          { 
           memset(&buffer[0], 0, sizeof(buffer)); 
          } 
          else cmdEXIT = 1; 
         } 
    
         else cmdEXIT = 1; 
        } 
    
        return 0; 
    } 
    

    スクリーンショットの結果:

    Client 2 being too bossy and not waiting for his turn to speak

  • +0

    なぜあなたは、2つのクライアントのために別々のコードが必要なのでしょうか? – e0k

    答えて

    0

    免責事項:自分でコードを実行していないため、以下の分析が間違っている可能性があります。

    戻り値がrecvであることを確認することをお勧めします。エラーの場合は-1が返されます。 whileループの開始時にrecvにClient2.cのこの行でエラーが発生した場合:recv(clientSocket, buffer, sizeof buffer - 1, 0);バッファがゼロになったままになります。

    このように、クライアント2は、クライアント1のメッセージを待たないだろう、と単純にこれのいずれかが助けたり、より多くの支援が必要な場合、私に教えてくださいクライアント1.

    からのメッセージに空の文字列を印刷します。上記が真である場合は、接続が中断されていないことを確認する必要があります。

    +0

    助けてくれてありがとう!それは問題の原因ではありませんでした(recvは空のメッセージで1に等しいことが判明しました)が、クライアントがお互いに待つ方法を見つけるのを助けました。 私は、後で同じ問題の答えを探す人のために私の解決策を提出します。 – ALar

    0

    これまでのコメントで約束したように、ここで私の解決策です。短いストーリーを短縮するには:私はrecvの価値が何であるかをテストする度に。1に等しい場合、メッセージは受信されず、「回線は空き」であり、クライアントは自分のメッセージを入力できます。さもなければ、彼は受け取ったメッセージを表示しなければならず、それから彼自身のテキストを送ることができます。

    Client1.c

    #include <stdio.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <string.h> 
    
    //fonction pour comparer deux strings : renvoie 0 si les valeurs sont égales 
    //et -1 sinon 
    
    int compare_strings(char a[], char b[]) 
    { 
        int c = 0; 
        while (a[c] == b[c]) 
        { 
         if (a[c] == '\0' || b[c] == '\0') 
         break; 
         c++; 
        } 
        if (a[c] == '\0' && b[c] == '\0') 
        return 0; 
        else 
        return -1; 
    } 
    
    
    int main() { 
        //déclaration des variables 
        int clientSocket; 
        char buffer[1024]; 
        struct sockaddr_in serverAddr; 
        socklen_t addr_size; 
        int cmdEXIT = 0; 
    
        //paramètrage du socket 
        clientSocket = socket(PF_INET, SOCK_STREAM, 0); 
        serverAddr.sin_family = AF_INET; 
        serverAddr.sin_port = htons(7891); 
        serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
        memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 
        addr_size = sizeof serverAddr; 
    
        //connection au serveur 
        connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); 
    
        //premier message du Client1 
        printf("Client 1 : "); 
        scanf(" %[^\n]s", buffer); 
        send(clientSocket,buffer,sizeof buffer - 1,0);  
    
        //continuer à envoyer et recevoir des messages 
        //tant qu'un des clients n'envoive pas "exit" 
        while (cmdEXIT == 0) 
        { 
         //si le message envoyé n'est pas "exit" 
         if (compare_strings(buffer, "exit")==-1) 
         { 
          //vider le buffer 
          memset(&buffer[0], 0, sizeof(buffer)); 
          //la valeur de recv qui est égale a 1 si recv n'a pas 
          //encore reçu de message 
          //sinon, elle est égale au nombre de bits reçu 
          int recvValue = recv(clientSocket, buffer, sizeof buffer - 1, 0); 
          //si recv n'est pas égal a 1 => un message a été reçu 
          if (recvValue != 1) 
          { 
           //si le contenu n'est pas "exit" 
           if (compare_strings(buffer, "exit")==-1) 
           { 
            //afficher le message du Client2 
            printf("Client 2 : "); 
            printf("%s\n", buffer); 
            //vider le buffer 
            memset(&buffer[0], 0, sizeof(buffer)); 
           } 
           //si Client2 a envoyé "exit" 
           else cmdEXIT=1; 
          } 
          //si rcv est égal a 1 => pas de message reçu 
          else 
          { 
           //Client1 peut saisir son message 
           printf("Client 1 : "); 
           scanf(" %[^\n]s", buffer); 
           //et l'envoyer à Client2 
           send(clientSocket,buffer,sizeof buffer - 1,0); 
          } 
         } 
         //sinon finir la boucle 
         else cmdEXIT=1; 
        } 
    
        return 0; 
    } 
    

    Server.c

    #include <stdio.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <string.h> 
    
    //fonction pour comparer deux strings : renvoie 0 si les valeurs sont égales 
    //et -1 sinon 
    int compare_strings(char a[], char b[]) 
    { 
        int c = 0; 
        while (a[c] == b[c]) 
        { 
         if (a[c] == '\0' || b[c] == '\0') 
         break; 
         c++; 
        } 
        if (a[c] == '\0' && b[c] == '\0') 
        return 0; 
        else 
        return -1; 
    } 
    
    int main() { 
        //déclaration des variables : Serveur et deux Clients 
        int welcomeSocket, Client1, Client2; 
        struct sockaddr_in serverAddr; 
        struct sockaddr_storage serverStorage; 
        socklen_t addr_size; 
        char buffer[1024]; 
    
        //paramètrage du Serveur 
        welcomeSocket = socket(PF_INET, SOCK_STREAM, 0); 
        serverAddr.sin_family = AF_INET; 
        serverAddr.sin_port = htons(7891); 
        serverAddr.sin_addr.s_addr = inet_addr("127.0.01"); 
        memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 
        bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); 
    
        //Serveur à l'écoute 
        if (listen(welcomeSocket,5)==0) 
         printf("Listening\n"); 
        else 
         printf("Error\n"); 
    
        //lier le serveur et les deux clients 
        addr_size = sizeof serverStorage; 
        Client1 = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size); 
        Client2 = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size); 
    
        int cmdEXIT = 0; 
        //continuer à recevoir et envoyer des messages 
        //tant qu'un des clients n'envoive pas "exit" 
        while (cmdEXIT == 0) 
        { 
         //recevoir le message de Client1 
         recv(Client1, buffer, 1024, 0); 
         //le renvoyer a Client2 
         printf ("%s\nEnvoie au Client2\n", buffer); 
         send(Client2,buffer,1024,0); 
         //sortir de la boucle si Client1 a envoyé "exit" 
         if (compare_strings(buffer, "exit")==0) 
         { 
          cmdEXIT = 1; 
         } 
         //sinon 
         else 
         { 
          //vider le buffer 
          memset(&buffer[0], 0, sizeof(buffer)); 
          //recevoir le message de Client2  
          recv(Client2, buffer, 1024, 0); 
          //le renvoyer a Client1 
          printf ("%s\nEnvoie au Client1\n", buffer); 
          send(Client1,buffer,1024,0); 
          //si Client2 a envoyé "exit" 
          if (compare_strings(buffer, "exit")==0) 
          { 
           cmdEXIT = 1; 
          } 
         } 
        } 
    
        return 0; 
    } 
    

    Client2.c

    #include <stdio.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <string.h> 
    
    //fonction pour comparer deux strings : renvoie 0 si les valeurs sont egales et -1 sinon 
    int compare_strings(char a[], char b[]) 
    { 
        int c = 0; 
        while (a[c] == b[c]) 
        { 
         if (a[c] == '\0' || b[c] == '\0') 
         break; 
         c++; 
        } 
        if (a[c] == '\0' && b[c] == '\0') 
        return 0; 
        else 
        return -1; 
    } 
    
    int main() { 
        //déclaration des variables 
        int clientSocket; 
        char buffer[1024]; 
        struct sockaddr_in serverAddr; 
        socklen_t addr_size; 
        int cmdEXIT = 0; 
    
        //paramètrage du socket 
        clientSocket = socket(PF_INET, SOCK_STREAM, 0); 
        serverAddr.sin_family = AF_INET; 
        serverAddr.sin_port = htons(7891); 
        serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
        memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 
        addr_size = sizeof serverAddr; 
    
        //connection au serveur 
        connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); 
    
        //continuer à envoyer et recevoir des messages 
        //tant qu'un des clients n'envoive pas "exit" 
        while (cmdEXIT == 0) 
        { 
         //la valeur de recv qui est égale a 1 si recv n'a pas 
         //encore reçu de message 
         //sinon, elle est egale au nombre de bits reçu 
         int recvValue = recv(clientSocket, buffer, sizeof buffer - 1, 0); 
         //si recv n'est pas égal a 1 => un message a été reçu 
         if (recvValue != 1) 
         { 
          //si le contenu n'est pas "exit"   
          if (compare_strings(buffer, "exit")==-1) 
          { 
           //afficher le message du Client1 
           printf("Client 1 : "); 
           printf("%s\n", buffer); 
           memset(&buffer[0], 0, sizeof(buffer)); 
    
          } 
          //sinon sortir de la boucle 
          else cmdEXIT = 1; 
         } 
         else 
         { 
          //Client2 peut saisir son message 
          printf("Client 2 : "); 
          scanf(" %[^\n]s", buffer); 
          //Client2 envoie son message au serveur 
          send(clientSocket,buffer,sizeof buffer - 1,0); 
          //si le contenu n'est pas "exit" 
          if (compare_strings(buffer, "exit")==-1) 
          { 
           //vider le buffer 
           memset(&buffer[0], 0, sizeof(buffer)); 
          } 
          //sinon sortir de la boucle 
          else cmdEXIT = 1; 
         } 
        } 
        return 0; 
    } 
    
    関連する問題