9

5 秒ごとにクライアントにデータを送信するサーバーがあります。サーバーがデータを送信してから印刷するまで、クライアントが read() をブロックするようにします。read() がデフォルトでブロックされていることは知っています。私の問題は、クライアントが read() をブロックしていないことです。これは非常に奇妙で、通常の問題ではないようです。

私のコードは、無限ループで「何も戻ってきませんでした」と出力します。私はLinuxマシンを使用しており、cでプログラミングしています。私のコードスニペットは以下です。ご意見をお聞かせください。

while(1)
{
    n = read(sockfd, recvline, MAXLINE);
    if ( n > 0) 
    {
        recvline[n] = 0;    
        if (fputs(recvline, stdout) == EOF)
            printf("fputs error");
    }
    else if(n == 0)
        printf("Nothing came back");
    else if (n < 0)
        printf("read error");
}
return; 
4

3 に答える 3

12

いくつかの原因が考えられ、さまざまな場所でいくつかの例外が発生する可能性があります。

  1. 作成するソケットを確認してください。

    sockfd=socket(AF_INET,SOCK_STREAM,0);  
    if (sockfd==-1) {
        perror("Create socket");
    }
    
  2. また、使用する前にブロックモードを明示的に有効にします。

    // Set the socket I/O mode: In this case FIONBIO  
    // enables or disables the blocking mode for the   
    // socket based on the numerical value of iMode.  
    // If iMode = 0, blocking is enabled;   
    // If iMode != 0, non-blocking mode is enabled.
    ioctl(sockfd, FIONBIO, &iMode);  
    

    setsockoptまたは、以下のように 使用できます。

     struct timeval t;    
     t.tv_sec = 0;
     tv_usec = 0;
     setsockopt(
          sockfd,     // Socket descriptor
          SOL_SOCKET, // To manipulate options at the sockets API level
          SO_RCVTIMEO,// Specify the receiving or sending timeouts 
          const void *(&t), // option values
          sizeof(t) 
      );   
    
  3. 読み取り関数呼び出しを確認してください(バグの理由)

    n = read(sockfd, recvline, MAXLINE);
    if(n < 0){  
        perror("Read Error:");
    }  
    
  4. サーバーコードも確認してください!:

    1. サーバーが空白の(印刷不可、null、入力)チャーターを送信する場合があります。そして、あなたはこれに気づいていません。サーバーコードにもバグがあります。

    2. または、クライアントが読み取る前にサーバーが終了しました。

  5. もう1つ興味深いことは、理解してみてください。

    サーバーでNを呼び出す場合write()、その必要はありませんread()。反対側でNを呼び出す必要があります。

于 2012-10-08T04:45:45.583 に答える
4

Greg Hewgill がコメントとして既に書いたこと: EOF (つまり、明示的な書き込みの停止、それが viaclose()または viaである場合) は、 0shutdown()を返すことによって受信側に伝達されます。 recv()'データではなく、読み取りループを終了できます。

ノンブロッキングが有効になっていてデータがない場合は、 を取得-1し、またはerrnoに設定されます。EAGAINEWOULDBLOCK

于 2012-10-08T05:12:35.633 に答える
2

MAXLINE の値は?

値が 0 の場合は、同様に 0 を返します。それ以外の場合は、Grijesh Chauhan が言及しているように、明示的にブロッキングに設定します。

または、ブロックと非ブロックを指定できる recv() の使用を検討することもできます。オプション MSG_WAITALL があり、すべてのバイトが到着するまでブロックします。

n = recv(sockfd, recvline, MAXLINE, MSG_WAITALL);
于 2012-10-08T05:02:01.940 に答える