Udpclient.receive from 未知随机端口

问题描述

我正在使用 UdpClient 发送消息并监听响应,如下所示:

Client = gcnew UdpClient();
HostEndPoint = gcnew IPEndPoint(192.168.0.20,52381);
Client->Connect(HostEndPoint);
Client->Send(Message,Message->Length);
Bytes = Client->Receive(HostEndPoint);

我有两个类似的设备,但它们的响应不同。在第一种情况下,目的地在我发送到的同一端口上做出响应。因此,例如,使用 49542 的随机源端口发送,会发生这种情况:

 Request: 192.168.1.10:49542 > 192.168.1.20:52381
Response: 192.168.1.20:52381 > 192.168.1.10:49542

使用上面的代码,我得到了预期的响应。

然而,另一个类似的设备以一个随机端口响应(它在电源循环时发生变化),如下所示:

 Request: 192.168.1.10:49542 > 192.168.1.20:52381
Response: 192.168.1.20:46468 > 192.168.1.10:49542

在这种情况下,我没有收到响应,Receive() 将超时。我相信我明白为什么没有收到任何东西。 .net 文档中建议,一旦您将 IPEndPoint 与 UdpClient() 或 Connect() 一起使用,任何其他响应都会被过滤掉。所以,我什至不知道为什么 Receive 有一个 IPEndPoint 参数。

我已经监控了与 WireShark 的通信,我可以看到双向的消息。所以我知道设备正在响应我只是不知道如何在我的代码中接收它。

我认为最好的解决方案是能够接收到达我的源随机端口(上面的 49542)的任何响应,另外还要指定目标 IP,但这可能不是必需的。或者,在任何端口上侦听来自目标 IP 的任何响应,因为我不知道如何知道设备正在响应哪个端口。

尽我所知,您必须为 Receive(IPEndPoint) 指定一个端口号,这通常是您首先发送到的消息的目标端口 - 就像我的代码示例中一样(有效与第一个设备)。 Connect 选择的随机端口无法监听,那是接收端口,但我认为 Receive 监听来自设备的发送端口。这是未知的。

我倾向于认为,我无法找到有关如何完成此操作的任何信息这一事实表明它无法完成,因为设备不应该从随机端口响应。但是,我已经与制造商讨论过这个问题,他们坚持认为这是正确的行为。

另请注意,我已尝试创建第二个 UdpClient 来侦听来自目标 IP 的响应,但它还需要定义一个端口,而且我无法知道要侦听哪个端口。我已经尝试过 UdpClient()->Client->RemoteEndPoint,但我很确定,这是我开始使用的端点,它具有已知端口,而不是随机端口。

这是我第一次遇到这种情况,对我来说似乎很奇怪。不过这些设备来自一家主要制造商,他们肯定知道他们在做什么。

解决方法

我相信我已经解决了这个问题。诀窍是不使用 Connect,而是在 Send 命令中传递 HostEndPoint。这种方法适用于两种设备。

Client = gcnew UdpClient();
HostEndPoint = gcnew IPEndPoint(192.168.0.20,52381);
// Client->Connect(HostEndPoint);
Client->Send(Message,Message->Length,HostEndPoint);
Bytes = Client->Receieve(HostEndPoint);

虽然它可以工作,但我不完全确定它会允许通过哪些消息。它可能允许来自指定 IP 的任何端口,或者它可能允许来自指定 IP 的任何响应定向到初始随机源端口。我不确定。

此外,我最初认为我可能必须在发送和接收之间设置 HostEndPoint->Port = 0。这有效,但没有必要。