19

The image below shows 2 processes that attempted and successfully bound listen sockets (server) to port 10000 on my local machine:

Sysinternals showing 2 binds on port 10000

and here's the output of netstat (for confirmation):

netstat -a -n | find "10000"
  TCP    0.0.0.0:10000          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:10000          0.0.0.0:0              LISTENING
  TCP    [::]:10000             [::]:0                 LISTENING

(NB: The javaw.exe process was the first to open the listen socket on 10000).

While I am aware of situations under which multiple processes can indeed listen on the same port (SO_REUSEADDR), there are certain things that bother me in my specific scenario:

  1. In my application, I specifically say to .NET that I want an exclusive listen socket (SO_EXCLUSIVEADDRUSE) via

    listener = new TcpListener(adr, ipport);
    listener.ExclusiveAddressUse = true;
    
  2. .NET does not throw any kind of exception / error / notification that the port is already in use. In fact, it actually believes that everything went fine.

  3. My server application never wakes up from the listener.AcceptTcpClient() call from this point on. The client application that is supposed to communicate with the server receives a valid connection but is unable to communicate with "my" server (supposedly because it establishes a connection to the "other" process which doesn't speak its "protocol").

In case someone wants to try and reproduce my findings: The 2nd process is the "Helios" release of Eclipse (PHP). But the specific process shouldn't matter here: If one process can do weird things under an OS, so can others.

Any advice on how I can either get an error or prevent such a situation (by means of additional parameters) altogether?

Community
  • 1
  • 1
MrCC
  • 714
  • 8
  • 20
  • [MSDN says](http://msdn.microsoft.com/ru-ru/library/system.net.sockets.tcplistener.exclusiveaddressuse.aspx) that the behaviour may depend on your OS (see Remarks there). Just guessing what to check. – Alexander Dunaev Nov 14 '12 at 01:59
  • [This](http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621%28v=vs.85%29.aspx) gives a more advanced overview over the exclusive address use, but it doesn't help as it doesn't seem to work "as advertised" (I'm on Win7) unless I'm missing something essential. – MrCC Nov 15 '12 at 08:01
  • I think this depends upon how the other process set up its socket. Specifically, I can't reproduce the issue with any of my existing open sockets. Nevertheless, I agree that you've found a problem with the .NET Framework, assuming it _is_ repeatable. – Mark Hurd Jan 01 '13 at 15:28

4 Answers4

4

The MSDN link you posted in your comment seems to answer your question.

It has to do with the java application binding to the wildcard IP endpoint (0.0.0.0 ip4; :: for ip6, or IPEndpoint.ANY). I'm assuming that the adr variable in your code snippet above is a specific IP address, and not also a wildcard address.

Take a look at the tables in that article. It lists the outcomes of trying to bind to either a specific or wildcard endpoint a second time, with different combinations of socket options.

In short, the Java code is binding on the wildcard 0.0.0.0 endpoint without the SO_EXCLUSIVEADDRUSE socket option. The matrix shows that when this happens, you can successfully bind to a specific address and pass requesting exclusive address use.

If you were to try and bind with a wildcard, the table shows that the call would fail.

Christopher Currens
  • 29,917
  • 5
  • 57
  • 77
1

Not sure why it's not throwing an exception. Although, the docs say TcpListener's constructor doesn't really validate whether the port is open or not, and so, it only throws an ArgumentException when the port number is invalid. Other methods, like Start will throw a SocketException with ErrorCode set to WSAEADDRINUSE (10048) when the port is already opened by another process (see Start method and Socket Error Codes).

To prevent this, either call Start and catch the SocketException or use the namespace System.Net.NetworkInformation to query for all ports used and figure out if a particular port is available, as in this answer: In C#, how to check if a TCP port is available?

Community
  • 1
  • 1
Diego
  • 18,035
  • 5
  • 62
  • 66
0

I believe you need to actually enable TCP port sharing - I'm on my phone right now, so best I can do at the moment is drop a link: Net.TCP Port Sharing

JerKimball
  • 16,584
  • 3
  • 43
  • 55
  • The article you link to is about the net.tcp:// protocol available in WCF, a Microsoft-custom TCP-derived protocol for communication. It sits "on-top" of TCP... – MrCC Nov 15 '12 at 07:57
  • Ah, mea culpa - should have read the question more carefully; yeah, TCP sharing won't help you in this case, I believe. – JerKimball Nov 15 '12 at 16:31
0

http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.exclusiveaddressuse.aspx - Notice some OS differences regarding ExclusiveAddressUse. Try Run as Administrator. Another thought, try going into your Computer Management -> Services and stopping the Net.Tcp Port Sharing Service.

Mark
  • 31
  • 4