Why do I have forbidden sockets?

I was tinkering with some C# code that uses TcpListeners recently, and hit on a strange issue where my code would run fine on on machine, and fail on another. It took me a while to find an answer in Google, so here’s a reminder to my future self:

The initial issue

In amongst the code I was running was a fragment like this:

_listener = new TcpListener(IPAddress.Loopback, 1234);

On my home laptop this ran fine, but on another computer it crashed with an unexpected exception:

For Google’s benefit, the stack trace was:

Unhandled exception. System.Net.Sockets.SocketException (10013): An attempt was made to access a socket in a way forbidden by its access permissions.
   at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
   at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Bind(EndPoint localEP)
   at System.Net.Sockets.TcpListener.Start(Int32 backlog)
   at System.Net.Sockets.TcpListener.Start()
   at Channels.ConnectionListener.Start() in C:\Users\JDavis\Source\Repos\ChannelsExperiment\Channels\ConnectionListener.cs:line 24
   at Channels.Wrapper.Start() in C:\Users\JDavis\Source\Repos\ChannelsExperiment\Channels\Wrapper.cs:line 24
   at Channels.Program.Main(String[] args) in C:\Users\JDavis\Source\Repos\ChannelsExperiment\Channels\Program.cs:line 23
   at Channels.Program.<Main>(String[] args)

My initial thought was “ah, there’ll be something else using that port…” but running “netstat -ano” didn’t show a hit against the loopback address I was trying to bind:

Active Connections
  Proto  Local Address          Foreign Address        State           PID
  TCP         ESTABLISHED     5604
  TCP         ESTABLISHED     5604
  TCP         ESTABLISHED     5604
  TCP         ESTABLISHED     5604
  TCP        ESTABLISHED     10852
  TCP         ESTABLISHED     4780

(I checked against the real IP address of the machine as well – nothing there either)

So I fell back on “it was a security error – maybe I have fewer rights on this machine?” and tried running Visual Studio (and also my test app) as admin. But no difference there either.

The answer…

After a pile of futher googling I hit upon an idea that was entirely new to me. It turns out code can reserve a port, without ever actually opening it. That means Windows will refuse you rights to use it for anything else – but it won’t show up on the netstat call shown above. And the refusal comes up as the odd security error above.

To work this out you need a different command: “netsh interface ipv4 show excludedportrange protocol=tcp” and for me that gives:

Protocol tcp Port Exclusion Ranges

Start Port    End Port
----------    --------
      1132        1231
      1232        1331
      1435        1534
      1555        1654
      1819        1918
     50000       50059     *

* - Administered port exclusions.

My code tried to open port 1234, and that is included in the second of these ranges… Bingo!

The critical info here came from this Stack Overflow answer, if you want to read the original source.

So I can use this info to pick a port that’s free on all my machines, and my little bit of test code can run happily.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.