DatagramSocket无法从UdpClient接收数据

Pey*_*man 3 c# datagram udpclient windows-runtime

我正在制作一个连接到桌面应用程序的Win RT应用程序,他们开始用UDP和TCP进行通信.

我已成功实现TCP通信,因为我可以从Win RT发送到桌面并从桌面发送到Win RT.在Win RT上使用StreamSocket,在桌面上使用TcpListener.

我还让它将Win RT中的Udp数据发送到桌面而没有任何问题.但我无法接收从桌面发送到Win RT的数据.我使用以下代码,我没有看到任何问题,但必须有一些东西.

    var g = new DatagramSocket();
    g.MessageReceived += g_MessageReceived;
    g.BindEndpointAsync(new HostName("127.0.0.1"), "6700");
    .
    .
    .
    void g_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
    { // <- break point here.

    }
Run Code Online (Sandbox Code Playgroud)

该断点永远不会停止代码,这意味着它永远不会得到消息.我只能想到IBuffer,因为在我的StreamSocket上我应该通过reader.GetBuffers()获取字节,而不是reader.GetBytes().然而,这是我需要在Win RT而不是桌面上考虑的事情.因为在Tcp上我只发送字节,我在Win RT中得到缓冲区,所以DatagramSocket也应该这样做.

  • reader = DataReader

感谢你们.

rei*_*rab 5

我不熟悉新的DatagramSocket类,但通常绑定到127.0.0.1意味着您只会收到发送到环回适配器的消息.由于您的数据包来自另一台主机,因此应该在NIC上接收它们,而不是环回适配器.

编辑:从查看您正在使用的DatagramSocket API的文档,您可以使用该BindServiceNameAsync()方法而不是BindEndpointAsync()为了绑定到所有适配器上的指定端口,这与我的System.Net.Sockets API的行为相同以下示例.所以,在你的例子中,你有:

g.BindServiceNameAsync("6700");
Run Code Online (Sandbox Code Playgroud)

当然,您还需要确保桌面主机上的防火墙设置允许它侦听指定端口上的传入UDP数据包.

请尝试以下代码:

    using System.Net;
    using System.Net.Sockets;

    public class UdpState
    {
        public UdpClient client;
        public IPEndPoint ep;
    }

    ...

    private void btnStartListener_Click(object sender, EventArgs e)
    {
        UdpState state = new UdpState();
        //This specifies that the UdpClient should listen on EVERY adapter
        //on the specified port, not just on one adapter.
        state.ep = new IPEndPoint(IPAddress.Any, 31337);
        //This will call bind() using the above IP endpoint information. 
        state.client = new UdpClient(state.ep);
        //This starts waiting for an incoming datagram and returns immediately.
        state.client.BeginReceive(new AsyncCallback(bytesReceived), state);
    }

    private void bytesReceived(IAsyncResult async)
    {
        UdpState state = async.AsyncState as UdpState;
        if (state != null)
        {
            IPEndPoint ep = state.ep;
            string msg = ASCIIEncoding.ASCII.GetString(state.client.EndReceive(async, ref ep));
            //either close the client or call BeginReceive to wait for next datagram here.
        }
    }
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的代码中,您显然应该使用您发送字符串的任何编码.当我编写测试应用程序时,我发送了ASCII字符串.如果您使用Unicode发送它,只需使用UnicodeEncoding.Unicode而不是ASCIIEncoding.ASCII.

如果这些都不起作用,您可能想要打破像Wireshark这样的数据包捕获实用程序,以确保来自RT主机的UDP数据包实际上是到达桌面主机.