18

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?

4

4 に答える 4

4

コメントに投稿したMSDN リンクは、あなたの質問に答えているようです。

これは、ワイルドカード IP エンドポイント ( 0.0.0.0ip4、::ip6 の場合は 、またはIPEndpoint.ANY) にバインドする Java アプリケーションに関係しています。adr上記のコード スニペットの変数は特定の IP アドレスであり、ワイルドカード アドレスでもないと想定しています。

その記事の表を見てください。ソケット オプションのさまざまな組み合わせを使用して、特定のエンドポイントまたはワイルドカード エンドポイントへのバインドを 2 回試みた結果を一覧表示します。

つまり、Java コードはソケット オプション0.0.0.0なしでワイルドカード エンドポイントにバインドされます。マトリックスは、これが発生すると、特定のSO_EXCLUSIVEADDRUSEアドレスに正常にバインドして、排他的アドレス使用の要求を渡すことができることを示しています。

ワイルドカードを使用してバインドしようとすると、呼び出しが失敗することが表に示されています。

于 2013-01-18T03:06:30.280 に答える
1

例外がスローされない理由がわかりません。ただし、ドキュメントによると、TcpListenerのコンストラクターはポートが開いているかどうかを実際には検証しないため、ArgumentExceptionポート番号が無効な場合にのみスローされます。ポートが別のプロセスによってすでに開かれている場合、(10048) に設定された aをStartスローするなどの他のメソッド( Start メソッドソケット エラー コードを参照)。SocketExceptionErrorCodeWSAEADDRINUSE

これを防ぐには、 を呼び出しStartてキャッチするSocketExceptionか、名前空間を使用して、System.Net.NetworkInformation使用されているすべてのポートをクエリし、特定のポートが使用可能かどうかを確認します。

于 2013-01-08T02:20:58.140 に答える
0

http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.exclusiveaddressuse.aspx - ExclusiveAddressUse に関する OS の違いに注意してください。管理者として実行してみてください。別の考えとして、[コンピューターの管理] -> [サービス] に移動し、Net.Tcp ポート共有サービスを停止してみてください。

于 2013-01-18T01:32:13.370 に答える
0

実際に TCP ポート共有を有効にする必要があると思います。私は今、電話を使用しているので、現時点でできる最善の方法は、リンクをドロップすることです: Net.TCP ポート共有

于 2012-11-14T16:47:45.973 に答える