UDP 客户端未收到来自具有多个 IP 地址的服务器的回复

Posted

技术标签:

【中文标题】UDP 客户端未收到来自具有多个 IP 地址的服务器的回复【英文标题】:UDP client not receiving reply from server with multiple IP addresses 【发布时间】:2016-05-26 18:12:40 【问题描述】:

我有一个调用 connect()、send() 和 recv() 的 UDP 客户端。

服务器有多个 IP 地址。如果来自服务器的回复不是来自与查询相同的 IP,则 recv() 超时。我在别处读到这可能是因为客户端正在调用 connect(),所以它只会接受来自同一 IP 的回复。

有没有办法确保服务器总是从与查询相同的 IP 回复?我希望服务器监听所有接口。

更新:如果客户端没有调用 connect() 并且调用了 sendto() 而不是 send(),那么 recv() 正确地接收到来自服务器的回复。我仍然宁愿通过从查询来自的同一 IP 发送回复来在服务器端修复它。服务器上没有发生路由,它是一个具有多个 IP 的网络接口。

【问题讨论】:

请写一个sn-p查看代码。另外我不相信 recv 失败,最多它不会收到任何东西。最后,如果中间有 NAT,我不相信服务器会在一个 IP 地址中接收消息并从不同的 IP 地址发送响应。如果您需要帮助,您应该提供更多详细信息 我应该更清楚。 recv() 超时。 如果我没记错的话,当传输到服务器时,客户端将通过 udp 包接收的端口号和 ip 建立通信。服务器应该返回相同的端口号。有时防火墙场景可能会导致问题,需要所谓的“udp 打孔”,但它与多客户端问题无关。如果您有多个客户端,则可以查看线程安全编码以将客户端分开。 在客户端和服务器上禁用防火墙以进行测试。数据报正在返回给客户端,但由于源 IP 地址不同,recv() 忽略了它。我已经确认,如果客户端不调用 connect() 并调用 sendto() 而不是 send(),则不会出现问题。 【参考方案1】:

如果客户端调用连接到一个 IP 地址和端口,这是有道理的,它不会收到从不同 IP 或端口发送的 UDP 数据报。

【讨论】:

感谢您帮助我。我理解为什么会这样,但希望在服务器上找到解决方案。我知道您要求提供代码示例。我试图把一个放在一起,但这是一个更大的库的一部分,所以代码并不都在一个地方。我认为现有代码没有任何问题,默认情况下它可以正常工作。我想更改默认行为以对传入和传出的数据报使用相同的 IP。 @upl8,服务器中的解决方案很简单。现在我了解您的问题,您不需要显示代码。基本上你必须让服务器通过它收到消息的同一个套接字发送响应。 我已经仔细检查过了,接收和发送的socket是一样的。看起来 Windows 只为 NIC 创建一个套接字,即使它有多个 IP。这是你所期望的吗?如果是这种情况,那么它不能仅从套接字知道要使用哪个 IP 地址。 @upl8,好吧,正如您在问题中解释的那样,您似乎通过 connect 和 sendto 解决了它。不看代码,我觉得没必要改服务器。你能显示客户端代码吗?您在客户端中遇到 recv() 超时的问题很可能是因为在客户端在发送消息后调用 recv 之前,服务器已经发送了响应,然后客户端没有读取它。当您在 UDP 中发送消息之前没有调用 bind 或 connect 时,可能会发生这种情况。在响应之前尝试在服务器中添加 sleep(1)。【参考方案2】:

如果您希望您的服务器监听所有 ip 和所有端口,您需要在以太网层(原始套接字)进行编程。看看这个link。

在原始套接字中编程时,您可以在代码中检查数据报所发送到的 IP 地址,并从相应的 IP 进行响应。

【讨论】:

以上是关于UDP 客户端未收到来自具有多个 IP 地址的服务器的回复的主要内容,如果未能解决你的问题,请参考以下文章

DHCP服务器的构建

当UDP协议客户端给TCP协议服务器发数据会发生什么

服务器端口未收到 UDP 消息

如何在同一本地/src 地址上创建多个 UDP 数据报通道/流

UDP打孔只能部分工作c#

TCP/IP网络编程:06基于UDP的服务器端/客户端