15

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
}
Community
  • 1
  • 1
brooc
  • 448
  • 2
  • 6
  • 10
  • 1
    What exception are you getting? – M.Babcock Feb 02 '12 at 21:14
  • @M.Babcock The exception message I am getting is: "An attempt was made to access a socket in a way forbidden by its access permissions" – brooc Feb 02 '12 at 21:24
  • Does your `udpServer` instance throw the same exception when try bind it? – M.Babcock Feb 02 '12 at 21:33
  • Doesn't appear that you are following the same code sample that was presented in the link in your question.. I see the IPAddress.Any, 6000 but what about UdpClient udpServer2 = new UdpClient(5000); and why are you not wrapping things like this in a Try{} catch{} – MethodMan Feb 02 '12 at 21:42
  • @M.Babcock If I'm not mistaken it is already bound when constructed with an endpoint. In any case I tried doing: udpServer.Client.Bind(localpt); right after setting the socket option and got a different exception message: "An invalid argument was supplied" – brooc Feb 02 '12 at 21:42
  • @DJKRAZE The code in the try catch in the original post is not the correct way to do it. It says KABOOM next to where that code throws an exception. I didn't wrap it with try catch because this is only for posting it here. – brooc Feb 02 '12 at 21:46
  • Have you looked at the MSDN Site they connect a bit different passoing the domainName, port http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.aspx For errors look at these 2 links http://msdn.microsoft.com/en-us/library/windows/desktop/cc150667%28v=vs.85%29.aspx | http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx – MethodMan Feb 02 '12 at 21:50

4 Answers4

32

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();
    }
sipsorcery
  • 30,273
  • 24
  • 104
  • 155
  • I have posted a followup question here: http://stackoverflow.com/questions/9140450/udp-hole-punching-implemetation-in-c-sharp – brooc Feb 04 '12 at 11:19
  • Why do you `Bind` on `localpt` and `Receive` on `inEndPoint`, is there a different? (If I `Receive` on `localpt` nothing seems to break) – Benjol Mar 19 '12 at 14:12
  • The Receive with inEndPoint will result in it holding the remote socket the packet came from. You could use localpt but then you won't have an easy way to know the local socket you've bound to. – sipsorcery Mar 19 '12 at 21:45
2

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.

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
MethodMan
  • 18,625
  • 6
  • 34
  • 52
  • Thanks, but I have found this information already. My code uses the SocketOptionName.ReuseAddress which I assume is essentially SO_EXCLUSIVEADDRUSE but in the .NET way. It seems there needs to be some other way to do this, but I can't seem to find it – brooc Feb 02 '12 at 22:01
  • I this is going to be a good puzzle.. I guess I am on the right track as well.. I will help to dig more and try code as well.. it's probably something so simple that even the most seasoned coder would over look it.. – MethodMan Feb 02 '12 at 22:03
  • Thanks, I have been looking at this for days... No luck... This is supposedly a very simple thing to do... Please try to run this code. – brooc Feb 02 '12 at 22:06
  • When you debug this are you getting 0.0.0:6000 for the localpt – MethodMan Feb 02 '12 at 22:22
  • this won't work because 0.0.0 isn't really an ip but anyway I will post my findings below not sure how the other individual claimed that they got it to work.. this does not seem / appear to be possible – MethodMan Feb 02 '12 at 22:31
0

To solve WSAEACCESS 10013 (MSDN) exception in UDP application you can try

udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
0

Even changing your code so that I can pass in an IP address I gets the same error message it appears that you can't bind to the same port and only one port can be used here is the sample code I used your example and Altered it to capture my ip from my local machine..

        IPAddress ipAddress = Dns.Resolve(Dns.GetHostName()).AddressList[0];
        IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 11000);

        //IPEndPoint localpt = new IPEndPoint(ipLocalEndPoint);

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

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

this will produce the exception on the Bind () method.. sorry.

MethodMan
  • 18,625
  • 6
  • 34
  • 52
  • There has got to be a way to do this. My aim is to create a system that incorporates UDP hole punching. This relies on the fact that I can listen on the same port that I am sending the data through... – brooc Feb 02 '12 at 22:42