是不是;所以“再利用港口”;(OS X)或;所以“你是谁?”;(Linux)真的允许用户对多个套接字使用recvfrom吗?

是不是;所以“再利用港口”;(OS X)或;所以“你是谁?”;(Linux)真的允许用户对多个套接字使用recvfrom吗?,c,linux,macos,sockets,udp,C,Linux,Macos,Sockets,Udp,我正在编写OSX(10.9.4)上UDP套接字的初学者代码,它使用绑定到同一IP地址和端口的多个UDP套接字。我认为使用SO_REUSEPORT将允许我通过多个套接字接收数据包。但在下面的示例中,两个套接字中只有一个可以接收数据(即client2,它将套接字绑定到client1之后的端口) 但我的预期结果如下 $ ./a.out Client 1 received: Hello Client 2 received: Hello Client 1 received: Hello

我正在编写OSX(10.9.4)上UDP套接字的初学者代码,它使用绑定到同一IP地址和端口的多个UDP套接字。我认为使用
SO_REUSEPORT
将允许我通过多个套接字接收数据包。但在下面的示例中,两个套接字中只有一个可以接收数据(即
client2
,它将套接字绑定到
client1
之后的端口)

但我的预期结果如下

$ ./a.out         
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: 
Client 2 received: 
(snip)

如何通过两个插座接收“Hello”?我还希望使代码与Linux(内核2.4)兼容。我尝试在Linux上使用
SO\u REUSEADDR
而不是
SO\u REUSEPORT
,但我在OS X上得到了相同的结果。

SO\u REUSEPORT
SO\u REUSEADDR
用于在程序完成后立即允许另一个应用程序(进程)使用相同的地址;它们与同一程序中的多线程无关

您看到的是两个线程收到已发送消息的通知,但只有线程2正在取消消息的请求,因为它是最后一个请求端口的线程

需要考虑的几件事:

服务器通常只在一个端口上侦听。没有理由指定远程地址,因为可以从客户端消息中获取远程地址。如果指定希望从中接收消息的客户端的地址和端口,则将无法处理来自任何其他客户端的请求

客户端通常(在某些特殊情况下,如FTP和NFS使用特定的客户端端口作为安全措施)打开一个新端口以与服务器通信。指定要连接的端口将限制同一台计算机上可以运行的客户端数量

此外,UDP(不包括多播)没有连接前导,因此在客户端向服务器发送消息之前,服务器无法知道客户端是否存在,更不用说它的地址了


我希望这有帮助;这里没有代码可以直接解决您的问题,因为它通常基于对UDP和socket编程的一些基本误解,但会颠倒您的工作(让客户端与服务器通信,服务器分别响应每个客户端)应该有助于更清楚地说明这一点。

感谢@Greyson澄清
,因此_REUSEPORT
不是为了实现我的目的。至少对我来说,OSX和Linux的手册页在这一点上并不清楚。请不要关心我的示例代码的细节。在realty中,我没有使用这种有点奇怪的客户机/服务器模型,事实上,它在我的应用程序中并不存在。
$ ./a.out         
Client 1 received: 
Client 2 received: Hello
Client 1 received: 
Client 2 received: Hello
Client 1 received: 
Client 2 received: Hello
Client 1 received: 
Client 2 received: Hello
Client 1 received: 
Client 2 received: Hello
Client 1 received: 
Client 2 received: Hello
Client 1 received: 
Client 2 received: Hello
Client 1 received: 
Client 2 received: Hello
Client 1 received: 
Client 2 received: Hello
Client 1 received: 
Client 2 received: Hello
$ ./a.out         
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: Hello
Client 2 received: Hello
Client 1 received: 
Client 2 received: 
(snip)