2016-04-16 9 views
0

Cのネットワークプログラミングに関する小さなプロジェクトに取り組んでいます。複数のクライアントが同時に接続する単純なグループチャットプログラム1つのサーバーであり、クライアントがメッセージを書き込むたびに、サーバーは他のすべてのクライアントにそのメッセージを送信します。1つのクライアントが受信したメッセージをサーバーに接続されている他のすべてのクライアントに送信できません

つまり、サーバーに接続されているすべてのクライアントが互いに通信できるグループチャットです。しかし、私は理解できない奇妙な問題を抱えています。

実行中のサーバー - >クライアントの実行 - >クライアントの実行 - >クライアントの実行 - >クライアント1がメッセージを入力したときに他のクライアントがそのメッセージを受信しない - >クライアント2がタイプするクライアント1のみがそのメッセージを受信します。>クライアント3がメッセージを入力すると、クライアント1とクライアント2の両方がそのメッセージを受信します。

何らかの理由で、このクライアントより前にサーバーに接続しているクライアントにのみ、クライアントからのメッセージが送信されるように動作します。クライアント3が1 & 2の後に接続されると、1 & 2は3番目のクライアントのメッセージを受信しましたが、3番目のクライアントは2番目のクライアントからメッセージを受信しません。

次は私が私のserver.cファイルで使用するコードです:

comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL); 
    arr[count++] = comm_fd; 
    printf("Client %d connected to the server!\n",comm_fd); 
    if ((childpid = fork()) == 0) { /*0 means child process*/ 
     do { 
     read(comm_fd,recvline,100); 
     printf("Client %d: %s",comm_fd,recvline); 
     if(strcmp(sendline,"bye\n") == 0) { 
      printf("Client %d left the chat!\n",comm_fd); 
      close(comm_fd); 
      exit(4); 
     } 
     for(int i=0; i<count; i++){ 
      if(arr[i]!=comm_fd) { 
      write(arr[i],recvline,strlen(recvline)+1); 
      } 
     } 
     } while(1); 
    } 

そして、これは私のいるclient.cです:

fgets(sendline,100,stdin); 
    write(sockfd,sendline,strlen(sendline)+1); 
    if(strcmp(sendline,"bye\n") == 0) { 
    printf("Closing connection!\n"); 
    exit(4); 
    } 
    bzero(sendline, 100); 
    if ((childpid = fork()) == 0) { 
    do{ 
     read(sockfd,recvline,100); 
     printf("%s",recvline); 
     if(strcmp(recvline,"bye\n") == 0) { 
     printf("\nA client left the chat group!\n\n"); 
     exit(4); 
     } 
     bzero(recvline, 100); 
    } while(1); 
    } 

誰もこれで私を助けることができますか?私はこの問題の解決策をたくさん探しましたが、答えを見つけることができませんでした。私はソケットプログラミングの初心者です。前もって感謝します!

+2

'fork()'はおそらくそのようなサーバのモデルです。新しい接続が受け入れられ、新しい子がforkされるたびに、 'arr []'配列の状態を考えてください。 – keithmo

答えて

3

それは クライアントによるメッセージのみ行動は理にかなっていることは、このクライアント

前に、サーバー に接続されているそれらのクライアントに送信されるような方法で作業し、いくつかの奇妙な理由で、あります私に - fork()は、メモリ/状態が親プロセスの現在の状態のコピーである子プロセスを作成します。つまり、親プロセスの変更(新しいクライアント接続の受け入れなど)は、 fork()呼び出しは既存の子プロセスに伝播されません。したがって、fork()を介して自身のサブプロセスが作成されたときに、すでに接続されているクライアントだけが各子プロセスに「参照」されます。

+0

私にも意味がある(Y)フォークされた子プロセスへの変更を更新する方法はありますか? –

+0

もちろん、stdinファイル記述子を介して、またはソケットやパイプなどで通信することができます。私はkeithmoのコメントに同意しますが、このようなことは、マルチプロセスやfork()を使用するよりも、単一のプロセス(selectイベントループやマルチスレッドなど)で簡単に簡単に実装できます。プロセスとスペースの分離は、あなたのために働いていて、あなたをあまり獲得していません。 –

関連する問題