根据connect()
的手册页,
如果套接字 sockfd 的类型为 SOCK_DGRAM,则 addr 是默认将数据报发送到的地址,也是接收数据报的唯一地址。
我有程序 A 在其套接字上调用地址为127.0.0.1 和端口 1212 的connect
,程序 B 在其套接字上调用bind
,地址为 IN_ADDRANY 和端口 1212。
当使用send
从程序A发送数据包时,程序B接收数据包并使用recvfrom
指示源地址实际上是127.0.0.1。
当程序 B 在其套接字上调用地址为 127.0.0.1 且端口 1212 在bind
之后调用connect
时,就会出现问题。当程序 A 发送数据包时,程序 B 将不再接收数据包。
这是预期行为吗?
我希望如此(哈哈) - 我认为问题是程序 B 的这是预期行为吗?
connect()
调用告诉 B 的 UDP 套接字它应该只接受来自 127.0.0.1:1212 的传入 UDP 数据包 - 但程序 A 的数据包实际上来自 127.0.0.1:xxxxxx,其中 xxxxx 是网络堆栈隐式绑定程序 A 的 UDP 套接字到的任意可用端口, 因为程序 A 从未显式调用bind()
(但 A 的 UDP 套接字需要绑定到端口才能工作send()
因为否则操作系统不知道如何在 UDP 数据包标头中填写源端口字段)
如果是这种情况,那么你的选择是让程序A在调用connect()
和send()
之前将其套接字显式bind()
到不同的已知端口,或者让程序B在调用connect()
之前以某种方式动态找出A从哪个端口发送,以便B可以将适当的端口号传递给connect()
。
或者我最喜欢的选择,即完全避免将connect()
与UDP套接字一起使用,而只使用sendto()
和recvfrom()
。 我发现这让我更好地控制了 UDP 发送/接收行为,因此减少了头痛。