2

次のコードが「java.net.BindException: Address already in use: JVM_Bind」例外をスローしないのはなぜですか?

import java.net.InetSocketAddress;
import java.net.ServerSocket;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        try (ServerSocket socket1 = new ServerSocket();
             ServerSocket socket2 = new ServerSocket();
             ServerSocket socket3 = new ServerSocket())
        {
            int port = 10000;

            socket1.setReuseAddress(false);
            socket1.bind(new InetSocketAddress("0.0.0.0", port));

            socket2.setReuseAddress(false);
            socket2.bind(new InetSocketAddress("127.0.0.1", port));

            socket3.setReuseAddress(false);
            socket3.bind(new InetSocketAddress("127.0.0.2", port));

            Thread.sleep(Long.MAX_VALUE);
        }
    }
}

その後「netstat」を実行すると、次のように表示されます。

C:\Users\Administrator>netstat -a -n | 検索文字列 10000
  TCP 0.0.0.0:10000 0.0.0.0:0 リスニング
  TCP 127.0.0.1:10000 0.0.0.0:0 リスニング
  TCP 127.0.0.2:10000 0.0.0.0:0 リスニング
  TCP [::]:10000 [::]:0 リスニング

これを Windows Server 2008 R2 (64 ビット) で実行していますが、'ipconfig /all' には 1 つのネットワーク アダプター/インターフェイスしか表示されません (他のネットワーク アダプターは無効になっています)。しかし、他の一部のマシンでは、このプログラムは実際に予期される「java.net.BindException: Address already in use: JVM_Bind」をスローします。

何が起こっているのでしょうか?

4

1 に答える 1

5

異なる IP アドレスの同じポート番号にバインドできます。オペレーティング システムは、着信パケットをターゲット IP アドレスと TCP ポート番号で区別できます。

127.0.0.1:1000オペレーティング システムは、とに対して別の serverSocket を保持しても問題ありません127.0.0.2:1000。新しい接続を開いたとしても、各パケットがどこに属しているかを認識しています。

0.0.0.0IPアドレスは単なるIPアドレスであることに注意してください(IPパケットがそこに送信されるという意味では有効なIPアドレスではありませんが、どちらもサポートできません0.0.0.0 == any)。すべてのアドレスをリッスンする場合は、null代わりに InetSocketAddress を指定してください。この時点で、目的の例外を取得する可能性が高くなります (OS が、ワイルドカード リッスンの優先度が低く、特定のリッスンと実際には重複しないと判断した場合を除きます。したがって、両方をバインドできます)。

setReuseAddressまた、設定はバインディングには影響しないことに注意してください。これは、どの接続が拒否または受け入れられるかの特定の部分にのみ影響します。

余談ですが、3 億年も待つことに何の意味があるのでしょうか。

于 2013-01-03T06:32:24.200 に答える