首页 文章

UWP DatagramsSocket不会触发MessageReceived

提问于
浏览
0

我正在研究一个应该通过TCP / UDP与远程设备通信的UWP应用程序 . 我的问题是UWP应用程序成功地将UDP消息发送到远程设备,但是没有收到回复 .

以下是从应用程序中提取的代码(简化):

async Task TestUdpIP()
{
    // Writer to the DatagramSocket
    DataWriter writer;

    using (var udpClient = new DatagramSocket())
    {
        try
        {
            // UDP Socket binding
            udpClient.MessageReceived += UdpClient_MessageReceived;
            var controllerName = new Windows.Networking.HostName(controllerIpAddress.ToString());
            await udpClient.BindEndpointAsync(controllerName, controllerIpPort.ToString());

            var remoteHostName = new Windows.Networking.HostName(hostIpAddres.ToString());
            await udpClient.ConnectAsync(remoteHostName, remoteHostPort.ToString());

            // Create a message to send
            string message = "Some message";

            // Reset the counter of messages received back from the remote robot
            messagesReceived = 0;

            // Send the message
            writer = new DataWriter(udpClient.OutputStream);
            writer.WriteString(message);
            await writer.StoreAsync();

            // Wait for robot status messages
            await Task.Delay(5000);              
        }
        catch
        {

        }
    }
}

void UdpClient_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    // Just increment the number of messages received
    messagesReceived++;
}

但是 UdpClient_MessageReceived 处理程序不会触发 . 我确信从UWP应用程序正确发送UDP消息,并且远程设备回复,如以下屏幕截图所示Wireshark(测试已在运行UWP应用程序的同一台PC上进行)

enter image description here
.

(IP地址,端口)详细信息显示在以下列表中,以便更好地解释上面的图片

  • UWP应用程序:(192.168.1.108,19000)发送和接收 .

  • 远程设备:(192.168.1.152,15999)接收和(192.168.1.152,54697)发送

Note: this is a similar question,答案说无论出于何种原因, DatagramSocket 应该在能够接收之前发送一些消息 . 在我的示例中,消息被发送出去但是接收到的消息处理程序无论如何都不会触发 .

Note: UWP应用程序已被授予互联网(客户端)和互联网(客户端和服务器)功能

Note: 我也试过这种(更可读的)方法来绑定UWP应用程序上的入站/出站数据报套接字,获得相同的结果:

// UDP Socket binding
var controllerName = new HostName(controllerIpAddress.ToString());
var remoteHostName = new HostName(hostIpAddres.ToString());
EndpointPair endpointpar = new EndpointPair(controllerName,
                                            controllerIpPort.ToString(),
                                            remoteHostName,
                                            remoteHostPort.ToString());
udpClient.MessageReceived += UdpClient_MessageReceived;
await udpClient.ConnectAsync(endpointpar);

问题在哪里?非常感谢!

2 回答

  • 0

    请尝试在应用清单中添加 Private Networks (Client & Server) 功能 .

    另一方面,您可以尝试使用官方DatagramSocket样本来查看这两个设备是否可以相互通信 .

  • 0

    经过一些实验,我想出了使用两个不同的 DatagramSocket 实例的想法:一个用于发送UDP消息,另一个用于侦听传入消息 . 使用此代码,我已经能够发送UDP消息 to 远程设备(如前所述),并且我已经能够接收远程设备的UDP消息 from .

    async Task TestUdpIP_DifferentPorts()
    {
        // Writer to the DatagramSocket
        DataWriter writer;
    
        // Inbound and outbound DatagramSocket
        DatagramSocket udpListener = new DatagramSocket();
        DatagramSocket udpSender = new DatagramSocket();
    
        try
        {
            // String containing the serializaed message
            string serializedMessage = "Some message";
    
            var controllerName = new HostName(controllerIpAddress.ToString());
            var remoteHostName = new HostName(hostIpAddres.ToString());
    
            // Bind listener
            udpListener.MessageReceived += UdpClient_MessageReceived;
            await udpListener.BindEndpointAsync(controllerName, controllerIpPort.ToString());
    
            // Connect sender
            await udpSender.ConnectAsync(remoteHostName, remoteHostPort.ToString());
    
            // Reset the counter of messages received back from the remote robot
            messagesReceived = 0;
    
            // Send the message
            writer = new DataWriter(udpSender.OutputStream);
            writer.WriteString(JsonConvert.SerializeObject(message));
            await writer.StoreAsync();
    
            // Wait for robot status messages
             await Task.Delay(1000);
        }
        catch (Exception ex)
        {
            // Some exception handling
        }
    
        udpSender.Dispose();
        udpListener.Dispose();
    
    }
    
    void UdpClient_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
    {
        // Just increment the number of messages received
        messagesReceived++;
    }
    

    使用此方法,只需指定入站侦听器的IP端口(或服务名称) . 该框架将选择下一个可用的出站IP端口 .

    Note: 如果我理解 DatagramSocket.ConnectAsync(EndpointPair) documentation,可以使用相同的 DatagramSocket 实例发送和侦听传入消息,因此我无法确定是否需要两个不同的实例 . 从文档:

    DatagramSocket上的此ConnectAsync(EndPointPair)方法用于定义使用OutputStream属性时将发送数据报的本地和远程 endpoints . 此方法还限制将在endpointPair参数中接受远程主机名的数据包的远程IP地址 . 只有与endpointPair参数中的远程 endpoints 匹配的传入数据包才会触发DatagramSocket上的MessageReceived事件 .

相关问题