web-dev-qa-db-ja.com

set / getsockopt SO_SNDBUFを理解する

こんにちは、UDPソケットの送信バッファーサイズを確認する次のプログラムがあります。ただし、戻り値は少しわかりにくいです。次のシンプルなアプリを使用します。

#include <sys/socket.h>
#include <stdio.h>

int main(int argc, char **argv)
{
 int sockfd, sendbuff;
 socklen_t optlen;

 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 if(sockfd == -1)
     printf("Error");

 int res = 0;

 // Get buffer size
 optlen = sizeof(sendbuff);
 res = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);

 if(res == -1)
     printf("Error getsockopt one");
 else
     printf("send buffer size = %d\n", sendbuff);

 // Set buffer size
 sendbuff = 98304;

 printf("sets the send buffer to %d\n", sendbuff);
 res = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff));

 if(res == -1)
     printf("Error setsockopt");


 // Get buffer size
 optlen = sizeof(sendbuff);
 res = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);

 if(res == -1)
     printf("Error getsockopt two");
 else
     printf("send buffer size = %d\n", sendbuff);

 return 0;
}

私のマシンの出力は次のとおりです。

送信バッファサイズ= 129024

送信バッファを98304に設定します

送信バッファサイズ= 196608

私がここで間違っていることや出力を解釈する方法を誰でも明確にできますか?

40
mortenvp

あなたは何も悪いことをしていません。 Linuxは、設定すると(カーネル内で)値を2倍にし、クエリすると2倍の値を返します。 man 7 socket言う:

 [...] 
 
 SO_SNDBUF 
最大ソケット送信バッファーをバイト単位で設定または取得します。 ker-
 nelは、setsockopt()を使用して設定されると、この値を2倍にします(簿記のオーバーヘッド用のスペースを確保するため)
。デフォルト値は
 wmem_default sysctlによって設定され、最大許容値は
 wmem_max sysctlによって設定されます。このオプションの最小(2倍)値は
 2048。
 [...] 
 
 NOTES 
 Linuxは送信の半分を想定しています/ receiveバッファーは、内部
カーネル構造に使用されます。したがって、sysctlは、ワイヤ上で観察できる
の2倍です。
 [...] 
52