sockets - UDP:为什么你不能在 `bind` 之后 `connect` ?

标签 sockets udp bind connect

这工作正常:

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

我们可以观察到本地和远程的正确绑定(bind):
$ 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:* 

但是把连接放在第一位,在绑定(bind)时得到一个错误,为什么?
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(通配符),用数字表示为 00.0.0.0struct sockaddr_in并且经常出现在 netstat 中, lsof等以上lsof输出显示指定了 4/5 个元素,远程端口保留为通配符)

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

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

p.s.有足够积分的人可以创建一个udp-connect标签? (甚至是 udp 绑定(bind))

最佳答案

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

编辑0:

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

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

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

编辑1:
connect(2)还根据到目的地的路由修复套接字本地地址。

关于sockets - UDP:为什么你不能在 `bind` 之后 `connect` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16874571/

相关文章:

c# - 重复使用套接字还是每次都创建一个新套接字?

c - 如何获得UDP校验和?

Cassandra DB - 绑定(bind)变量

c - SOL_SOCKET 有什么用?

c - 套接字recv函数不返回更新的值

.net - 如何处理异步套接字中的超时?

c# - 没有对象类型 'ImagePacket'的程序集ID。序列化异常捕获C#

python - "An integer is required error received for UDP server"

Haskell:用 do-notation 定义 FoldM

JavaScript function.prototype.bind polyfill