多个客户端的C#.NET UDP套接字异步

时间:2015-07-19 10:29:43

标签: c# .net sockets udpclient

我一直在寻找,我无法找到我需要的东西,特别是对于UDP。

我正在尝试使用端口514(UDP)监听基本的syslog服务器。

我一直关注MSDN上的Microsoft指南: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次交易后我遇到了来自套接字的“用完缓冲区空间”错误。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

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

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

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

删除所有异步代码。

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

答案 1 :(得分:-1)

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);
        }​