【问题标题】:UDP Sending / Receiving in .NET.NET 中的 UDP 发送/接收
【发布时间】:2011-08-12 15:17:57
【问题描述】:

我是 UDP 新手。使用测试环境,我能够发送/接收单个 UDP 消息。但是,我试图弄清楚如何接收多个 UDP 消息。我希望 MyListener 服务在我发送它们时全天接收 UDP 数据包。感谢您的帮助。

PS - 如下面的回答中所述,如果我在 DoSomethingWithThisText 周围放置一段时间(true),则在调试时将起作用。但是,当尝试将 MyListener 作为服务运行时它不会起作用,因为 Start 永远不会超过 while(true) 循环。

我的监听服务看起来像这样...

public class MyListener
{
    private udpClient udpListener;
    private int udpPort = 51551;

    public void Start()
    {
        udpListener = new UdpClient(udpPort);
        IPEndPoint listenerEndPoint = new IPEndPoint(IPAddress.Any, udpPort);
        Byte[] message = udpListener.Receive(ref listenerEndPoint);

        Console.WriteLine(Encoding.UTF8.GetString(message));
        DoSomethingWithThisText(Encoding.UTF8.GetString(message));
    }
}

我的发件人如下所示:

static void Main(string[] args)
{
    IPAddress ipAddress = new IPAddress(new byte[] { 127, 0, 0, 1 });
    int port = 51551;

    //define some variables.

    Console.Read();
    UdpClient client = new UdpClient();
    client.Connect(new System.Net.IPEndPoint(ipAddress, port));
    Byte[] message = Encoding.UTF8.GetBytes(string.Format("var1={0}&var2={1}&var3={2}", new string[] { v1, v2, v3 }));
    client.Send(message, message.Length);
    client.Close();
    Console.WriteLine(string.Format("Sent message");
    Console.Read();
}

【问题讨论】:

    标签: c# .net udpclient


    【解决方案1】:

    您应该在一段时间内或其他循环中调用接收。

    【讨论】:

    • 如果我在我的 DoSomethingWithThisText 周围添加一个 while(true) 循环,这确实有帮助,但它只适用于调试器。如果我尝试将 MyListener 作为服务运行,该服务将在启动时超时,因为它永远不会超过 while(true) 循环。
    【解决方案2】:

    我最终使用了 Microsoft 的异步方法,在此处找到 - BeginReceiveEndReceive

    就像 Microsoft 建议的那样,我在 Start 方法中调用 BeginReceive,如下所示:

    UdpState s = new UdpState();
    s.e = listenerEP;
    s.u = udpListener;
    
    udpListener.BeginReceive(new AsyncCallback(ReceiveCallback), s);
    

    但是,为了让侦听器继续接收消息,我在 ReceiveCallback 函数中递归地调用 BeginReceive AGAIN。这当然是潜在的内存泄漏,但我在回归测试中还没有遇到问题。

    private void ReceiveCallback(IAsyncResult ar)
    {
        UdpClient u = (UdpClient)((UdpState)ar.AsyncState).u;
        IPEndPoint e = (IPEndPoint)((UdpState)ar.AsyncState).e;
    
        UdpState s = new UdpState();
        s.e = e;
        s.u = u;
        udpListener.BeginReceive(new AsyncCallback(ReceiveCallback), s); 
    
        Byte[] messageBytes = u.EndReceive(ar, ref e);
        string messageString = Encoding.ASCII.GetString(messageBytes);
    
        DoSomethingWithThisText(messageString);
    }
    

    【讨论】:

    • 这里没有资源泄漏,因为您调用了EndReceive,与每个读取操作相关的所有资源都会被正确清理。请注意,这些天ReadAsync 可能更可取。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    相关资源
    最近更新 更多