sendto(..)
UDP ポートとして開かれたソケットの呼び出しに渡すことができる最大バイト数を取得するにはどうすればよいですか?
3 に答える
getsockopt() を使用します。このサイトには、取得できる使用方法とオプションの詳細が記載されています。
Windows では、次のことができます。
int optlen = sizeof(int); int optval; getsockopt(socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (int *)&optval, &optlen);
Linux の場合、UDP のマニュアル ページによると、カーネルは MTU 検出を使用します (ここと宛先の間の最大 UDP パケット サイズを確認し、それを選択します)。MTU 検出がオフの場合は、最大サイズをインターフェイス MTU に変更し、それより大きいものをフラグメント化します。イーサネット経由で送信する場合、通常の MTU は 1500 バイトです。
Mac OS X では、送信 (SO_SNDBUF) と受信 (SO_RCVBUF) で異なる値があります。これは送信バッファのサイズです (man getsockopt):
getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (int *)&optval, &optlen);
より大きなメッセージ (ローカル ループバック経由で送信された UDP の Leopard 9216 オクテット) を送信しようとすると、「メッセージが長すぎます / EMSGSIZE」という結果になります。
UDP は接続指向ではないため、2 つのパケットが一緒に属していることを示す方法はありません。その結果、1 つの IP パケットの最大サイズ (65535) によって制限されます。IP パケットのサイズには IP ヘッダー (通常 20 バイト) と UDP ヘッダー (8 バイト) も含まれているため、送信できるデータはそれよりやや少なくなります。
この IP パケットは、より小さいパケットに収まるように断片化できることに注意してください (例: イーサネットの場合は ~1500 バイト)。
これをさらに制限しているOSについては知りません。
ボーナス
SO_MAX_MSG_SIZE
UDPパケットの
- IPv4: 65,507 バイト
- IPv6: 65,527 バイト