c# - DatagramSocket 无法从 UdpClient 接收数据

标签 c# windows-runtime datagram udpclient

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

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

我还可以毫无问题地将 Udp 数据从 Win RT 发送到桌面。但是我无法接收从桌面发送到 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.

    }

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

  • reader = 数据读取器

谢谢你们。

最佳答案

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

编辑:通过查看您正在使用的 DatagramSocket API 的文档,您可以只使用 BindServiceNameAsync() 方法而不是 BindEndpointAsync( ) 以便绑定(bind)到所有适配器上的指定端口,这与下面我的 System.Net.Sockets API 示例的行为相同。因此,在您的示例中,您将拥有:

g.BindServiceNameAsync("6700");

当然,您还需要确保桌面主机上的防火墙设置允许它在指定端口上监听传入的 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.
        }
    }

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

如果这些都不起作用,您可能需要使用 Wireshark 等数据包捕获实用程序来确保来自 RT 主机的 UDP 数据包确实到达了桌面主机。

关于c# - DatagramSocket 无法从 UdpClient 接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13656372/

相关文章:

c# - 多页 PrintDocument 中的不同方向(如何)

c# - 将具有子实体的实体添加到 Redis 服务器导致 System.StackOverflowException

c# - Azure 移动服务同步上下文 : Adding custom parameters

binding - 如何在 WinRT 中的 ItemContainerStyle 中进行绑定(bind)?

c# - 在 Metro 应用程序中打开媒体文件

sockets - 读取UDP套接字: records or stream

c# - 应付发票捕获或提取自动化

php - 用PHP连接到DTLS

java - Android 2.0.1(目前在 DROID 上)的多播是否损坏,或者我错过了什么?

c# - 在 C# 中确定字符串的编码