简体   繁体   中英

C# .NET UDP Sockets Async for Multiple Clients

I have been looking around and I can't really find what I need, especially for UDP.

I'm trying to make a basic syslog server listening on port 514 (UDP).

I have been following Microsoft's guide on MSDN: https://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive(v=vs.110).aspx

It doesn't clearly state (or I'm blind) how to re-open the connection for more packets to be recieved.

Here is my code (basically the same from the link)

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

I have tried reiteration but I'm running into 'Running out of buffer space' error from the socket after 2 transactions.

Any ideas?

If you insist on using the obsolete APM pattern you need to make ReceiveCallback issue the next BeginReceive call.

Since UDP is connectionless async IO seems pointless. Probably, you should just use a synchronous receive loop:

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

Delete all that async code.

If you insist on async IO at least use ReceiveAsync .

The msdn code has a sleep which you eliminated. You don't need the sleep, but you do need a block. Try these changes

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM