IPPROTO_UDPはいつ必要ですか?
UDPがnot SOCK_DGRAMのデフォルトプロトコルである場合はありますか? (実際の場合、架空の「そうかもしれない」ではありません」)
つまり、次の2行がnot同じ動作を生成する状況は何ですか?
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
if ((s=socket(AF_INET, SOCK_DGRAM, 0))==-1)
これらの宣言を考えると:
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
raw_socket = socket(AF_INET, SOCK_RAW, protocol);
ip(7) Linuxのマニュアルページには次のように書かれています。
プロトコルの有効な値は、TCPソケットの場合は0とIPPROTO_TCP、UDPソケットの場合は0とIPPROTO_UDPのみです。SOCK_RAWの場合、RFC1700の割り当て番号で定義されている有効なIANAIPプロトコルを指定できます。
質問のこれらの2行は、常に同じ結果を生成します。
一部のオペレーティングシステム(2.6.20以降のLinuxカーネルなど)は、UDP-Liteと呼ばれるSOCK_DGRAMの2番目のプロトコルをサポートしています。システムでサポートされている場合は、socket()呼び出しの3番目の引数としてIPPROTO_UDPLITEを指定することで有効になります。
チェックサムをデータグラムの一部にのみ適用できるようにすることで、通常のUDPとは異なります。 (通常、UDPチェックサムはオールオアナッシングの取り組みです。)こうすることで、チェックサム領域外の一部のフラグメントが転送中に失われた場合に、プロトコルはフラグメント化された送信によるチェックサム障害に対してより耐性があります。チェックサム部分をカバーするフラグメントが正常に受信されている限り、可能な限り多くのデータグラムがアプリケーションに配信されます。
既存のコードとの下位互換性のために、UDP-Liteを追加でサポートするシステムでも、呼び出しソケット(AF_INET、SOCK_DGRAM、0)がデフォルトで通常のUDPになり続けると思われます(ただし、保証はできません)。