1. ホーム
  2. c

[解決済み] ソケットライブラリでrecvを呼び出す場合、recvバッファはどの程度の大きさにすべきでしょうか?

2022-05-03 04:23:24

質問

C言語のソケットライブラリについていくつか質問があります。以下は、私が質問で参照するコードのスニペットです。

char recv_buffer[3000];
recv(socket, recv_buffer, 3000, 0);

  1. recv_buffer の大きさはどのように決めればよいのでしょうか? 私は3000を使っていますが、これは任意です。
  2. の場合、どうなるのでしょうか? recv() は、私のバッファよりも大きなパケットを受信しますか?
  3. 受信するものがないのに recv を再度呼び出して永久に待たせることなく、メッセージ全体を受信したかどうかを知るにはどうしたらよいでしょうか。
  4. バッファの容量が一定でない場合、容量不足を心配せずにバッファに追加し続けることができる方法はありますか? strcat を連結して、最新の recv() のレスポンスをバッファに保存しますか?

一度にたくさんの質問をしてしまいましたが、ご回答いただけると大変助かります。

どのように解決するのですか?

これらの質問に対する答えは、ストリームソケットを使用しているかどうかによって異なります ( SOCK_STREAM ) またはデータグラムソケット ( SOCK_DGRAM TCP/IP内では、前者がTCP、後者がUDPに相当します)。

に渡されるバッファの大きさはどのようにして知ることができるのでしょうか? recv() ?

  • SOCK_STREAM : それはあまり重要ではありません。 もしあなたのプロトコルがトランザクション/インタラクティブなものであれば、合理的に期待される最大の個々のメッセージ/コマンドを保持できるサイズを選んでください(おそらく3000で大丈夫です)。 もしあなたのプロトコルが大量のデータを転送するものであれば、より大きなバッファがより効率的です。良い経験則は、ソケットのカーネル受信バッファサイズとほぼ同じです(多くの場合、256kB程度)。

  • SOCK_DGRAM : アプリケーションレベルのプロトコルが送信する最大のパケットを保持するのに十分な大きさのバッファを使用してください。 UDPを使用している場合、一般的にアプリケーションレベルのプロトコルは約1400バイトより大きいパケットを送信するべきではありません。

以下の場合はどうなりますか? recv は、バッファより大きなパケットを取得しますか?

  • SOCK_STREAM : ストリームソケットにはパケットという概念がなく、単にバイトの連続した流れだからです。 もし、バッファの容量以上のバイトを読み込むことができれば、それらはOSによってキューに入れられ、次の recv .

  • SOCK_DGRAM : 余分なバイトは破棄される。

メッセージをすべて受信したかどうかを確認するにはどうしたらよいですか?

  • SOCK_STREAM : アプリケーションレベルのプロトコルに、メッセージの終わりを判断する何らかの方法を組み込む必要があります。 一般的には、長さのプレフィックス(各メッセージをメッセージの長さで始める)か、メッセージの終わりのデリミタ(例えばテキストベースのプロトコルでは単なる改行かもしれません)を使用します。 あまり使われていませんが、3つ目のオプションは、各メッセージのサイズを固定にすることです。 これらのオプションの組み合わせも可能です。たとえば、長さの値を含む固定サイズのヘッダーなどです。

  • SOCK_DGRAM : シングル recv の呼び出しは常に1つのデータグラムを返す。

バッファの容量が一定でない場合、容量不足を心配せずにバッファを追加し続けることができる方法はありますか?

ただし、バッファのサイズを変更するために realloc() (で割り当てられていた場合)。 malloc() または calloc() ということです)。