1

私のプログラムの目的は、select を使用して複数のソケットを管理することです。しかし、まずはソケット1つでやってみようと思いました。今、私が直面している問題は、最初にクライアントがサーバーにデータを送信し、サーバーがそれを受信して​​表示することですが、クライアントが再びデータを送信すると、サーバーコードは選択コマンドのままになります。

ここに、ソケットをどのように初期化しているかを示すいくつかのスニペットがあります。

if((master_socket = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
      exit(1);
    }

    if((bind(master_socket, (struct sockaddr *)&req, sizeof(req))) < 0)
    {
      exit(1);
    }

    listen(master_socket, 5);
    FD_SET(master_socket,&listening);

    /* wait for connection, then receive and print text */
    len = sizeof(struct sockaddr);
    while(1)
     {
            FD_ZERO(&listening);  //Flush out everything in socket
        FD_SET(master_socket,&listening); // Add master
        if(f_client>0)           // Add client if any
        {
            FD_SET(f_client,&listening);
        }
        printf("Checking for new connection \n");
           //Timeout is null, so waiting indefinitely
        rc = select(FD_SETSIZE, &listening, NULL, NULL, NULL);

     if (FD_ISSET(master_socket, &listening))
        {
          printf("Master side invoked\n");
          if((f_client = accept(master_socket, (struct sockaddr *)&req, &len)) < 0)
          {
             exit(1);
              }
            }

    else if (FD_ISSET(f_client,&listening))
    {
         if ((valread = read( f_client , buf, 1024)) == 0)
         {
            close(f_client);
            f_client=0;
         }
         else
         {
            fputs(buf, stdout);  
         }

    }

}

基本的に上記のプログラムでは、サーバーに接続し、クライアントのファイル記述子を維持してf_client追加します。そして、すべてのラウンドで、ソケットをクリアし、マスター ソケットとクライアント ソケット (存在する場合) を追加してから、チェックします。ここでの問題は、最初は機能しますが、クライアントがデータを送信するのは 2 回目です。それはハングアップしますrc = select(FD_SETSIZE, &listening, NULL, NULL, NULL);

ここで何が悪いのか理解できません。誰でも助けることができますか?

4

1 に答える 1

4
     if ((valread = read( f_client , buf, 1024)) == 0)
     {
        close(f_client);
        f_client=0;
     }
     else
     {
        fputs(buf, stdout);  
     }

このコードは壊れています。このfputs関数は、C スタイルの文字列でのみ使用できます。特定の構造を持たない任意のデータがあります。を無視valreadしているため、読み取ったバイト数もわかりません。(考えてみてくださいfputs。出力するバイト数をどうやって知ることができるでしょうか? その情報は にしかなく、その情報をvalread渡しません。)

あなたはすでにデータを受け取っていますが、この壊れたコードはそれを捨てただけです. をログに記録すると、 への呼び出しがハングする前に、valreadへの最後の呼び出しで実際に既にそれを読んでいることがわかります。readselect

の代わりにfputs、次のようなものを使用できます。

for (int i = 0; i < valread; ++i)
   putchar(buf[i]);
于 2013-01-27T21:22:58.140 に答える