0

1: サーバーはファイル サイズをバッファにコピーして送信します。

  snprintf(t_buf, 255, "%" PRIu32, fsize);
  if(send(f_sockd, t_buf, sizeof(t_buf), 0) < 0){
    perror("error on sending file size\n");
    onexit(f_sockd, m_sockd, 0, 2);
  }

2: クライアントはファイル サイズを受け取り、それを fsize に入れます。

  if(recv(f_sockd, t_buf, sizeof(t_buf), 0) < 0){
    perror("error on receiving file size");
    onexit(f_sockd, 0 ,0 ,1);
  }
  fsize = atoi(t_buf);

----------------- 上記のコードにより、私のプログラムは完璧に動作します!

前のコードの代わりにこのコードを書くと、問題が発生します:
1: サーバーが fsize を送信します:

  if(send(f_sockd, &fsize, sizeof(fsize), 0) < 0){
    perror("error on sending file size\n");
    onexit(f_sockd, m_sockd, 0, 2);
  }

2: クライアントは fsize を受け取ります。

  if(recv(f_sockd, &fsize, sizeof(fsize), 0) < 0){
    perror("error on receiving file size");
    onexit(f_sockd, 0, 0, 1);
  }

どこuint32_t fsize;char t_buf[256];
問題は、最初の方法ではすべてが機能しますが、2 番目の方法ではクライアントがすべてのファイルを受け取るのではなく、その一部だけを受け取ることです。このコードの何が問題になっていますか?
ありがとう!

4

2 に答える 2

1

recv(2)は必ずしも完全な出力バッファーを埋めるわけではありません - 利用可能なデータの量に応じて、より少ないバイトを返す場合があります:

受信呼び出しは通常、要求された全量の受信を待つのではなく、要求された量までの利用可能なデータを返します。

戻り値 (> 0 の場合) は受信したバイト数になるため、すべてを確実に受信したい場合はループで呼び出すことができます。

MSG_WAITALLまたは、次のフラグを渡すこともできます。

このフラグは、完全な要求が満たされるまで操作をブロックすることを要求します。ただし、シグナルがキャッチされた場合、エラーまたは切断が発生した場合、または次に受信されるデータが返されたデータとは異なるタイプである場合、呼び出しは要求されたよりも少ないデータを返すことがあります。

したがって、あなたの場合、次のようなことができます:

ssize_t bytes = recv(f_sockd, &fsize, sizeof(fsize), MSG_WAITALL);

if(bytes == sizeof(fsize))
{
    /* received everything */
}
else
{
    /* something went wrong */
}
于 2012-08-29T10:35:38.313 に答える
0

より多くのデータがないと判断するのは困難です。

エンディアンである可能性があります。の値を出力する必要がありますfsize

recv()コメントで述べたように、からの部分的なリターンである可能性もあります。

于 2012-08-29T10:34:09.370 に答える