2

クライアントがサーバーに何かを書き込み、それがクライアントにエコーバックされる単純なtcpサーバー/クライアントアプリを作成しました。ただし、サーバーがクライアントにエコーバックしたものを読み取ろうとすると、いくつかの問題が発生します。

string s;
while((n = read(socketFD[0],readBuf, BUFFER_SIZE)) > 0){
  cout<<"\nBytes read: "<<n<<endl;
  s.append(readBuf, n);
}
cout<<"\nTest after read\n";

サーバーに16KBのテキストを書き込みます。クライアントで読んでいるときは、一度に4KBを読んでいます。

このコードからの出力は次のとおりです。

Bytes read: 4096

Bytes read: 4096

Bytes read: 4096

Bytes read: 4046

読み取り呼び出しは、ソケットからの読み取りが完了した後にブロックされ、ループを離れることはないようです。どうすればこれを修正できますか?

編集:これは、接続されたクライアントを処理するサーバー内のコードです。

if((childpid = fork()) == 0){
  close(listenFD);
  while ((n = read(connectFD, buf, BUFFSIZE)) > 0){
    cout<<"\nBytes read: "<<n<<endl;
    write(connectFD, buf, n);
  }
  cout<<"\nTest after read\n";
  exit(0);
}

この出力は次のとおりです。

Bytes read: 4096

Bytes read: 4096

Bytes read: 4096

Bytes read: 4046

Test after read

ここでは、クライアントのコードと何が違うのですか?クライアントの場合とは異なり、読み取り呼び出しがブロックされないのはなぜですか?

4

3 に答える 3

0

読み取りループを別のスレッドに入れたくない場合は、ポーリングまたは選択する必要があります。そうすれば、実際に読み取ることなく、キューに何かが存在するかどうかを確認できます

于 2012-11-24T16:08:38.383 に答える
0

読み取り呼び出しは、ソケットからの読み取りが完了した後にブロックされ、ループを離れることはないようです。どうすればこれを修正できますか?

read簡単に言えば、すべてのデータを受け取った後で電話をかけないでください。

その時点で受信したいすべてのデータを受信したことを検出するコードを記述し、受信した場合はループを終了します。実際に何らかのプロトコルを実装する必要があります。

s+=readBuf;

それは正しくありえません。追加するデータのバイト数をどのようにして知ることができsますか?

于 2012-11-24T16:11:01.213 に答える
0

これは、Pythonのソケットの非常に優れた紹介からの抜粋です。Pythonですが、C-Socket APIを公開しているので、そこに書かれていることはあなたのコンテキストにも当てはまります。ここで読むことができます:http://docs.python.org/dev/howto/sockets.html

「ソケットの使用」に関するセクションでは、観察している問題を正確に説明しています。関数について説明しますが、それはファイル記述子上の関数にrecv変換されます。read

ただし、ソケットを再利用してさらに転送する場合は、ソケットにEOTがないことを理解する必要があります。繰り返します。0バイトを処理した後にソケットsendまたはrecvが戻った場合、接続は切断されています。接続が切断されていない場合は、(今のところ)これ以上読み取るものがないことをソケットが通知しないため、recvを永久に待つことができます。少し考えてみると、ソケットの基本的な真実に気付くでしょう。メッセージは、固定長(yuck)、区切り文字(shrug)、またはメッセージの長さ(はるかに優れている)、または接続をシャットダウンして終了します。選択は完全にあなた次第です(しかし、いくつかの方法は他の方法よりも正しいです)。

于 2012-11-24T16:46:03.977 に答える