UDP:为什么不能在`connect`之后`绑定`?

时间:2013-06-01 16:01:09

标签: 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

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

$ 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个中的一些可以是任何(通配符),在0中以数字形式表示为0.0.0.0struct sockaddr_in,并且通常在netstatlsof中表示,上面的lsof输出显示指定的4/5元素,远程端口保留为通配符)

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

我想尝试并检查当一个应用程序绑定了一个端口而没有指定发件人地址时,另一个应用程序可以连接&绑定对等体,形成更完整的元组。 [请注意,第一个应用未指定SO_REUSEADDR]

P.S。有足够积分的人可以创建一个udp-connect标签吗? (甚至是udp-bind)

1 个答案:

答案 0 :(得分:1)

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

编辑0:

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

然后是多播,它允许你创建完全重复的套接字绑定,但只能创建一个特定的地址类,你需要做更多的工作来设置它。

在我看来,你对TCP侦听与连接套接字的混淆也很混乱。

编辑1:

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