【问题标题】:Unexpected behavior with connected UDP sockets连接的 UDP 套接字的意外行为
【发布时间】:2018-04-12 22:34:22
【问题描述】:

根据connect() 的手册页,

如果套接字 sockfd 是 SOCK_DGRAM 类型,那么 addr 是默认发送数据报的地址,也是接收数据报的唯一地址。

我有程序 A 在其套接字上调用connect,地址为 127.0.0.1 和端口 1212,程序 B 在其套接字上调用bind,地址为 IN_ADDRANY 和端口 1212。​​

当程序 A 使用 send 发送数据包时,程序 B 接收数据包并使用 recvfrom 指示源地址实际上是 127.0.0.1。

当程序 B 在其套接字上调用connect 时,问题就出现了,地址为 127.0.0.1,端口为 1212,位于bind 之后。当程序 A 发送数据包时,程序 B 将不再接收数据包。

这是预期的行为吗?

【问题讨论】:

    标签: linux sockets udp


    【解决方案1】:

    这是预期的行为吗?

    我希望如此(哈哈)——我认为问题在于程序 B 的 connect() 调用告诉 B 的 UDP 套接字它应该只接受来自 127.0.0.1:1212 的传入 UDP 数据包——但程序 A 的数据包是实际上来自 127.0.0.1:xxxxx,其中 xxxxx 是网络堆栈隐含地将程序 A 的 UDP 套接字绑定到的任意可用端口,因为程序 A 从未显式调用 bind()(但 A 的 UDP 套接字需要绑定到一个端口send() 可以工作之前,否则操作系统不知道如何填写 UDP 数据包头中的源端口字段)

    如果是这种情况,那么您的选择是让程序 A 在调用 connect()send() 之前明确地将其套接字 bind() 连接到不同的知名端口,或者让程序 B 以某种方式动态地找出什么端口 A 在调用 connect() 之前发送,以便 B 可以将适当的端口号传递给 connect()

    或者我最喜欢的选项,即完全避免将connect() 与UDP 套接字一起使用,而只使用sendto()recvfrom()。我发现这让我可以更好地控制 UDP 发送/接收行为,从而减少麻烦。

    【讨论】:

    • 哦,这很有道理,非常感谢!我确实想使用sendto()recvfrom() 路由提供它提供的所有灵活性,但我认为调用connect 可能会将一些处理卸载到网络接口,这会很棒,因为我正在处理高带宽数据.
    猜你喜欢
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    相关资源
    最近更新 更多