2

この論文http://www.brynosaurus.com/pub/net/p2pnat/で説明されているように、NAT の TCP ホール パンチングのプロトタイプを作成しようとしています。

特定のローカル ポートでサーバーへの接続を開こうとする単純なコードがあります。NAT が両方の接続を同じ NAT マッピングにマップするかどうか、公開サーバーで観察しようとしています。

int localPort = getFreeLocalPort();

     while (true) {

        Socket connection = new Socket(_publicServerHost,_publicServerPort,
                 getLocalSocketAddress(), localPort);

        connection.setReuseAddress(true);

        connection.close();

     }

1回目は問題なく繋がります。しかし、2回目の試行で例外がスローされます:

穴あけ用に選択されたローカル ポート: 65416

2012-06-17 15:55:21,545 エラー - アドレスは既に使用されています: 接続

2012-06-17 15:55:25,175 DEBUG - 詳細: java.net.BindException: アドレスは既に使用されています: java.net.PlainSocketImpl.socketConnect(Native Method) で接続 ~[na:1.6.0_24] at java.net .PlainSocketImpl.doConnect(PlainSocketImpl.java:351) ~[na:1.6.0_24] at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213) ~[na:1.6.0_24] at java.net.PlainSocketImpl.connect (PlainSocketImpl.java:200) ~[na:1.6.0_24] at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) ~[na:1.6.0_24] at java.net.Socket.connect(Socket.java) :529) ~[na:1.6.0_24] at java.net.Socket.connect(Socket.java:478) ~[na:1.6.0_24] at java.net.Socket.(Socket.java:375) ~[ na:1.6.0_24] java.net.Socket.(Socket.java:249) ~[na:1.6.0_24]

4

3 に答える 3

1

connection.setSoLinger(true, 0);connection.close(); の直前に追加してみてください。

そのようです:

connection.setSoLinger(true, 0);
connection.close();

これにより、OS は強制的にソケットを解放します。

于 2012-06-17T20:13:41.320 に答える
0

ローカル ポートはどのような基準で選択されましたか? 明らかに健全なものではありません。ゼロを指定してシステムに選択させ、必要な場合は開いた後にソケットから実際の値を取得する方がよいでしょう。

于 2012-06-17T21:28:49.500 に答える
0

あなたの問題は解決しましたか?ポートが割り当てられる前に setReuseAddress() を呼び出す必要があります。

Socket connection = new Socket();
connection.setReuseAddress(true);
connection.bind( ...);
于 2013-02-20T13:39:50.813 に答える