Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connecting two UDP clients to one port (Send and Receive)

I tried the suggestion from this question with very little success.

Please... any help will be greatly appreciated!

Here is my code:

static void Main(string[] args)
{

    IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);

    UdpClient udpServer = new UdpClient(localpt); 
    udpServer.Client.SetSocketOption(
        SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

    UdpClient udpServer2 = new UdpClient();
    udpServer2.Client.SetSocketOption(
        SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

    udpServer2.Client.Bind(localpt); // <<---------- Exception here
}
like image 999
brooc Avatar asked Feb 02 '12 21:02

brooc


People also ask

Can UDP send and receive on same port?

TCP vs UDP Once connected, a TCP socket can only send and receive to/from the remote machine. This means that you'll need one TCP socket for each client in your application. UDP is not connection-based, you can send and receive to/from anyone at any time with the same socket.

Can UDP handle multiple clients?

Because UDP socket is a connectionless service, it is able to accept several concurrent connections from different remote hosts. The packet multiplexing must be done in user application.

Can multiple clients send data to the same UDP socket used by a server?

If you have two threads both calling recvfrom() on the same socket, then any given incoming UDP packet will be delivered to either one thread or the other, and it's impossible to predict which thread will receive which packet -- it will just be luck of the draw depending on what is the next packet in the socket's ...

Can you send and receive from the same socket?

You can send and receive on the same socket at the same time (via multiple threads). But the send and receive may not actually occur simultaneously, since one operation may block the other from starting until it's done.


2 Answers

You have to set the socket option before binding.

    static void Main(string[] args)
    {
        IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);

        UdpClient udpServer = new UdpClient();
        udpServer.Client.SetSocketOption(
            SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpServer.Client.Bind(localpt);

        UdpClient udpServer2 = new UdpClient();
        udpServer2.Client.SetSocketOption(
            SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

        udpServer2.Client.Bind(localpt); // <<---------- No Exception here

        Console.WriteLine("Finished.");
        Console.ReadLine();
    }

Or a more illustrative example:

    static void Main(string[] args)
    {
        IPEndPoint localpt = new IPEndPoint(IPAddress.Loopback, 6000);

        ThreadPool.QueueUserWorkItem(delegate
        {
            UdpClient udpServer = new UdpClient();
            udpServer.ExclusiveAddressUse = false;
            udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            udpServer.Client.Bind(localpt);

            IPEndPoint inEndPoint = new IPEndPoint(IPAddress.Any, 0);
            Console.WriteLine("Listening on " + localpt + ".");
            byte[] buffer = udpServer.Receive(ref inEndPoint);
            Console.WriteLine("Receive from " + inEndPoint + " " + Encoding.ASCII.GetString(buffer) + ".");
        });

        Thread.Sleep(1000);

        UdpClient udpServer2 = new UdpClient();
        udpServer2.ExclusiveAddressUse = false;
        udpServer2.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpServer2.Client.Bind(localpt);

        udpServer2.Send(new byte[] { 0x41 }, 1, localpt);

        Console.Read();
    }
like image 184
sipsorcery Avatar answered Sep 25 '22 14:09

sipsorcery


I looked up your error message and this explains what the error is and why it is happening.

Here is the exact error message and reason WSAEACCES 10013 (MSDN)

Permission denied.

An attempt was made to access a socket in a way forbidden by its access permissions. An example is using a broadcast address for sendto without broadcast permission being set using setsockopt(SO_BROADCAST).

Another possible reason for the WSAEACCES error is that when the bind function is called (on Windows NT 4.0 with SP4 and later), another application, service, or kernel mode driver is bound to the same address with exclusive access. Such exclusive access is a new feature of Windows NT 4.0 with SP4 and later, and is implemented by using the SO_EXCLUSIVEADDRUSE option.

like image 28
MethodMan Avatar answered Sep 21 '22 14:09

MethodMan