【问题标题】:IPPROTO_IP vs IPPROTO_TCP/IPPROTO_UDPIPPROTO_IP 与 IPPROTO_TCP/IPPROTO_UDP
【发布时间】:2011-07-20 02:38:19
【问题描述】:

我在查找有关socket 的第三个参数的这些设置之间的区别的文档时遇到了一些麻烦。我知道 TCP 和 UDP 及其差异,而且 IP 是堆栈上的一层(下?)...无论我将其设置为 IPPROTO_IP 还是 IPPROTO_UDP,我的 UDP 代码似乎都一样。

【问题讨论】:

    标签: sockets ip


    【解决方案1】:

    Linux 上socket() 的文档分为多个联机帮助页,包括ip(7),它指定您必须对UDP 使用0IPPROTO_UDP,对TCP 使用0IPPROTO_TCP。当你使用0时,恰好是IPPROTO_IP的值,UDP用于SOCK_DGRAM,TCP用于SOCK_STREAM

    在我看来,创建 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。通过始终指定 socktypeprotocol,您可以避免任何歧义。

    【讨论】:

      【解决方案2】:

      来自socket(2) Linux 手册页,来自man-pages 5.08:

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

      IPPROTO_IP 只是来自IPPROTO_* 系列的常用占位符常量,在socket API 中具有值0,因为its early days

      当然,为了向前兼容,如果将来为协议族添加更多套接字类型,这可能会破坏 0 与 UDP/TCP 或改变其行为,最好查找您想要的协议的特定协议值并使用它,而不是使用0IPPROTO_IP

      请注意,IPPROTO_* 标头值在不同的上下文中有多种用途:除了在套接字 API 和内部实现代码中用作参数值来标识协议之外,它们还用作IP 数据包本身中的 IP 协议字段。这些 IP 协议值或 protocol numbers in IANA terminology 本身还有一个附加用途 identifying different extension header types in IPv6。这就是为什么 0 也是 IPPROTO_HOPOPTS,即 IPv6 Hop-by-Hop Option 扩展标头的标识符的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-29
        • 2011-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-23
        • 1970-01-01
        相关资源
        最近更新 更多