【问题标题】:UDP: Why can't you `bind` after a `connect`?UDP:为什么在“连接”之后不能“绑定”?
【发布时间】:2013-06-01 16:01:08
【问题描述】:

这很好用:

socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
setsockopt(4, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(4, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("1.1.1.1")}, 16) = 0

我们可以观察到本地和远程的正确绑定:

$ sudo lsof -Pni :4444
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
udpdup  2815 nhed    4u  IPv4 126724      0t0  UDP 10.0.2.15:4444->1.1.1.1:* 

但是先连接,绑定的时候报错,为什么?

socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
setsockopt(4, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("1.1.1.1")}, 16) = 0
bind(4, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EINVAL (Invalid argument)





我为什么在乎你问?

我认为接收到的数据包与一个 5 元素元组(proto、loc addr、loc port、rem addr、rem port)匹配。其中 5 个中的一些可以是 ANY(通配符),在 struct sockaddr_in 中用数字表示为 00.0.0.0,并且通常在 netstatlsof 等中表示。上面的 lsof 输出显示 4 /5 指定元素,远程端口保留为通配符)

我不记得是否应该存在多个套接字,其中一些具有通配符对等地址,而另一些可能是显式的,根据最佳匹配将流量发送到正确的端口。

我想试验并检查当一个应用程序绑定一个端口而不指定发送者地址时,另一个应用程序可以连接并绑定对等点,以形成一个更完整的元组。 [注意第一个app没有指定SO_REUSEADDR]

附言有足够积分的人可以创建一个udp-connect标签吗? (甚至是 udp 绑定)

【问题讨论】:

  • 如果你要拿分(-1)那么请评论为什么

标签: sockets udp bind connect


【解决方案1】:

connect(2) 隐式绑定您的本地端口,因此后续显式 bind(2) 失败。

编辑0:

您可以将多个套接字绑定到同一个本地端口,但第一个之后的所有绑定都必须更具体。比如说,第一个套接字绑定到INADDR_ANY,其他的绑定到现有网络接口的特定地址。请注意,所有套接字必须设置为SO_REUSEADDR

然后是多播,它允许您创建完全重复的套接字绑定,但仅限于特定类别的地址,并且您必须做更多的工作来设置它。

在我看来,您也将此与 TCP 侦听与连接的套接字混淆了。

编辑 1:

connect(2) 还根据到目的地的路由固定套接字本地地址。

【讨论】:

  • 是的,绑定一个临时的本地端口,所以指定4/5的唯一方法是先绑定,所以基本上我在最后一段中描述的内容是不可能的?
  • 请放心,我不会将它与 TCP 混为一谈。联机帮助页(2):“如果套接字 sockfd 是 SOCK_DGRAM 类型,则 addr 是默认发送数据报的地址,也是接收数据报的唯一地址”
猜你喜欢
  • 1970-01-01
  • 2014-06-19
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 2012-05-28
  • 2021-07-15
  • 1970-01-01
  • 2014-02-14
相关资源
最近更新 更多