【发布时间】:2010-12-29 15:18:38
【问题描述】:
什么时候需要 IPPROTO_UDP?
是否存在 UDP 不是不是 SOCK_DGRAM 的默认协议的情况? (真实案例,不是假设的“它可能是”,拜托“)
即,以下两行会不产生相同行为的情况是什么?
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
if ((s=socket(AF_INET, SOCK_DGRAM, 0))==-1)
【问题讨论】:
什么时候需要 IPPROTO_UDP?
是否存在 UDP 不是不是 SOCK_DGRAM 的默认协议的情况? (真实案例,不是假设的“它可能是”,拜托“)
即,以下两行会不产生相同行为的情况是什么?
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
if ((s=socket(AF_INET, SOCK_DGRAM, 0))==-1)
【问题讨论】:
某些操作系统(例如 2.6.20 之后的 Linux 内核)支持 SOCK_DGRAM 的第二种协议,称为 UDP-Lite。如果您的系统支持,可以通过提供 IPPROTO_UDPLITE 作为 socket() 调用的第三个参数来启用它。
它与普通 UDP 的区别在于它允许校验和仅应用于数据报的一部分。 (通常,UDP 校验和是一项全有或全无的工作。)这样,如果校验和区域之外的某些片段可能在传输过程中丢失,协议可以更好地抵抗由于分段传输而导致的校验和失败。只要成功接收到覆盖校验和部分的片段,仍然会向应用程序传递尽可能多的数据报。
为了与现有代码的向后兼容性,我怀疑(但我不能保证)调用 socket(AF_INET,SOCK_DGRAM,0) 将继续默认为普通 UDP,即使在额外支持 UDP-Lite 的系统中也是如此。
【讨论】:
鉴于这些声明:
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
raw_socket = socket(AF_INET, SOCK_RAW, protocol);
linux 中的ip(7) 手册页说:
协议的唯一有效值是 0 和 IPPROTO_TCP 用于 TCP 套接字,以及 0 和 IPPROTO_UDP 用于 UDP 套接字。 对于 SOCK_RAW,您可以指定一个有效的 RFC 1700 中定义的 IANA IP 协议 分配的数字。
你问题中的这两行总是会产生相同的结果。
【讨论】:
IPPROTO_UDP intsead 与您得到一个要求您填写所有标题的套接字的结果不同。