Sockets IPPROTO_IP与IPPROTO_TCP/IPPROTO_UDP

Sockets IPPROTO_IP与IPPROTO_TCP/IPPROTO_UDP,sockets,ip,Sockets,Ip,我很难找到关于socket的第三个参数的这些设置之间的区别的文档。我知道TCP和UDP及其区别,也知道IP是堆栈上的上(下)一层。。。无论我将其设置为IPPROTO\u IP还是IPPROTO\u UDP,我的UDP代码似乎都能正常工作 Linux上的socket()文档分为不同的手册页,包括ip(7),其中指定必须使用0或IPPROTO\u UDP进行UDP,使用0或IPPROTO\u TCP进行TCP。当您使用0时,它恰好是IPPROTO_IP的值,UDP用于SOCK_DGRAM,TCP用于

我很难找到关于
socket
的第三个参数的这些设置之间的区别的文档。我知道TCP和UDP及其区别,也知道IP是堆栈上的上(下)一层。。。无论我将其设置为
IPPROTO\u IP
还是
IPPROTO\u UDP
,我的UDP代码似乎都能正常工作

Linux上的
socket()
文档分为不同的手册页,包括
ip(7)
,其中指定必须使用
0
IPPROTO\u UDP
进行UDP,使用
0
IPPROTO\u TCP
进行TCP。当您使用
0
时,它恰好是
IPPROTO_IP
的值,UDP用于
SOCK_DGRAM
,TCP用于
SOCK_流

我认为创建UDP或TCP IPv4套接字对象的干净方法如下:

int sock_udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
int sock_tcp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
原因是,一般来说,显性的比隐性的好。在这种特定情况下,对第三个参数使用
0
或更糟的
IPPROTO_IP
,并不会给您带来任何好处

还可以想象使用一个协议,它可以同时处理流和数据报,比如sctp。通过始终指定socktype和protocol,您可以避免任何歧义。

socket(2)
Linux手册页,从
手册页
5.08:

通常只有一个协议支持 给定协议族中的特定套接字类型,在这种情况下 协议可以指定为0。然而,有可能许多 协议可能存在,在这种情况下,必须使用特定的协议 以这种方式指定

IPPROTO\u IP
只是
IPPROTO\u
*族中的常用占位符常量,其值为
0

当然,出于前向兼容性的考虑,如果将来为协议系列添加更多套接字类型,这可能会破坏UDP/TCP的
0
,或改变其行为,最好查找所需协议的特定协议值并使用它,而不是使用
0
IPPROTO\u IP

请注意,
IPPROTO\uu
*头值在不同的上下文中有多种用途:除了用作参数值来标识套接字API中的协议及其实现代码中的内部协议外,它们还用作IP数据包本身中IP协议字段的值。这些IP协议值或其本身有一个额外的用途。这就是为什么
0
也是
IPPROTO\u HOPOPTS
,IPv6逐跳选项扩展标头的标识符