【问题标题】:C# .NET UDP Sockets Async for Multiple Clients用于多个客户端的 C# .NET UDP 套接字异步
【发布时间】:2015-07-19 10:29:42
【问题描述】:

我一直在四处寻找,但我真的找不到我需要的东西,尤其是对于 UDP。

我正在尝试创建一个基本的 syslog 服务器侦听端口 514 (UDP)。

我一直在关注微软在 MSDN 上的指南:https://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive(v=vs.110).aspx

它没有明确说明(或者我是瞎子)如何重新打开连接以接收更多数据包。

这是我的代码(与链接基本相同)

     static void Main(string[] args)
    {
        try
        {
            ReceiveMessages();

            Console.ReadLine();

        }catch(SocketException ex)
        {
            if(ex.SocketErrorCode.ToString() == "AddressAlreadyInUse")
            {
                MessageBox.Show("Port already in use!");
            }
        }

    }

    public static void ReceiveMessages()
    {
        // Receive a message and write it to the console.



        UdpState s = new UdpState();

        Console.WriteLine("listening for messages");
        s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s);
        RecieveMoreMessages(s);
    }

    public static void RecieveMoreMessages(UdpState s)
    {
        s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s);
    }

    public static void ReceiveCallback(IAsyncResult ar)
    {
        UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u;
        IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e;

        Byte[] receiveBytes = u.EndReceive(ar, ref e);
        string receiveString = Encoding.ASCII.GetString(receiveBytes);

        Console.WriteLine("Received: {0}", receiveString);
    }

我已尝试重复,但在 2 次事务后我遇到了来自套接字的“缓冲区空间不足”错误。

有什么想法吗?

【问题讨论】:

    标签: c# .net sockets udpclient


    【解决方案1】:

    如果您坚持使用过时的 APM 模式,您需要拨打ReceiveCallback 发出下一个BeginReceive 电话。

    由于 UDP 是无连接的异步 IO 似乎毫无意义。可能,您应该只使用同步接收循环:

    while (true) {
     client.Receive(...);
     ProcessReceivedData();
    }
    

    删除所有异步代码。

    如果你坚持异步 IO,至少使用ReceiveAsync

    【讨论】:

    • 如果你认为它已经过时了,我应该如何使用“新”的东西。
    • 通过访问这些新功能的文档并将它们输入到 Google 中。实际上,既然这些功能和旧的功能一样,应该不会有太大的麻烦。
    【解决方案2】:

    您消除了 msdn 代码的睡眠。你不需要睡眠,但你确实需要一个街区。试试这些改变

           public static void ReceiveMessages()
            {
                // Receive a message and write it to the console.
    
    
    
                UdpState s = new UdpState();
    
                Console.WriteLine("listening for messages");
                s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s);
                //block
                while (true) ;
            }
    
            public static void RecieveMoreMessages(UdpState s)
            {
                s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s);
            }
    
            public static void ReceiveCallback(IAsyncResult ar)
            {
                UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u;
                IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e;
    
                Byte[] receiveBytes = u.EndReceive(ar, ref e);
                string receiveString = Encoding.ASCII.GetString(receiveBytes);
    
                Console.WriteLine("Received: {0}", receiveString);
                RecieveMoreMessages(ar.AsyncState);
            }​
    

    【讨论】:

    • while (true) ; 这确实不是暂停线程的方法,因为它将核心驱动到 100%。我也看不出这有什么作用。
    • 阅读一个块。块阻止程序退出。它内置在表单项目中,但您需要将块添加到控制台应用程序。您可以添加睡眠或任何其他停止处理的方法
    猜你喜欢
    • 1970-01-01
    • 2019-09-09
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多