8

次のコードセグメントがどのように、そしてなぜ機能するのか理解できません。

    /* Now lets try to set the send buffer size to 5000 bytes */
    size = 5000;
    err = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,  &size, sizeof(int));
    if (err != 0) {
        printf("Unable to set send buffer size, continuing with default size\n");
    }

送信バッファの値を確認すると、実際には5000 * 2 = 10000に正しく設定されています。ただし、送信バッファサイズを超えて送信しようとすると、すべてが送信されます。例えば:

    n = send(sockfd, buf, 30000, 0);

    /* Lets check how much us actually sent */
    printf("No. of bytes sent is %d\n", n);

これにより、30000が出力されます。

これはどの程度正確に機能しましたか?送信バッファのサイズが10000に制限されていたという事実は効果がありませんでしたか?もしそうなら、正確には何が起こったのですか?ある種の断片化?

更新:ソケットが非ブロッキングモードの場合はどうなりますか?私は次のことを試しました:

  1. バッファサイズを10000(5000 * 2)に変更すると、16384バイトが送信されます
  2. バッファサイズを20000(10000 * 2)に変更すると、30000バイトが送信されます

もう一度、なぜですか?

4

2 に答える 2

14

オプション設定の効果はSO_SNDBUF、TCP と UDP で異なります。

  • UDP の場合、これはデータグラムのサイズに制限を設定します。つまり、それより大きいものは破棄されます。
  • TCP の場合、これは特定のソケットのカーネル内バッファーのサイズを設定するだけです (ページ境界への丸めと上限付き)。

あなたがTCPについて話しているように見えるので、あなたが観察している効果は、ソケットがブロックモードにあることによって説明されるためsend(2)、カーネルがすべてのデータを受け入れることができるまでブロックし、ネットワークスタックがデータを非同期的にデキューしてプッシュします。これにより、バッファ内のスペースが解放されます。

また、TCP はストリーム プロトコルであり、「メッセージ」構造を保持しません。1 つは反対側のsend(2)複数の に対応でき、その逆も可能です。recv(2)バイトストリームとして扱います。

于 2011-11-13T20:22:52.477 に答える
4

SO_SNDBUFソケット実装が内部的に使用するバッファを構成します。ソケットがブロックされていない場合、構成されたサイズまでしか送信できません。ソケットがブロックされている場合、呼び出しに制限はありません。

于 2011-11-13T20:24:36.563 に答える