2016-08-27 53 views
0

我正在使用Java NIO作爲點對點協議,並且需要創建多個同時連接,其中很多會失敗。不幸的是,似乎我需要等待連接建立之前建立下一個,否則我會得到一個「BindException:不能分配請求的地址:連接」。有沒有人有一個想法如何解決這個問題?在Java中同時創建多個傳出連接NIO

for (NetworkAddress address : addresses) { 
    if (isConnectedTo(address)) { 
     continue; 
    } 
    try { 
     SocketChannel channel = SocketChannel.open(); 
     channel.configureBlocking(false); 
     channel.connect(new InetSocketAddress(address.toInetAddress(), address.getPort())); 
     // admittedly, 20 seconds is quite long 
     long timeout = System.currentTimeMillis() + 20_000; 
     while (!channel.finishConnect() && System.currentTimeMillis() < timeout) { 
      // Without this loop, I get said exception 
     } 
     if (!channel.finishConnect()) { 
      channel.close(); 
      continue; 
     } 
     ConnectionInfo connection = new ConnectionInfo(ctx, CLIENT, 
      address, 
      listener, 
      requestedObjects, 0 
     ); 
     connections.put(
      connection, 
      channel.register(selector, OP_READ | OP_WRITE, connection) 
     ); 
    } catch (NoRouteToHostException | AsynchronousCloseException ignore) { 
    } catch (IOException e) { 
     LOG.error(e.getMessage(), e); 
    } 
} 
+0

永遠不要發生異常,不要處理它。 Like your noroutetohostexception – Jens

+0

連接完成之前您無法使用連接,但可以有任意數量的掛起連接。 –

+0

@Jens:我幾乎同意,但我希望有一些主機沒有路由,除了嘗試下一個主機外,沒有什麼可做的。另一個也是預期的(發生在關閉時),但如果發生在其他場合,我可能想記錄它。 – Chris

回答

0

不能使用連接之前,它已經完成連接,但你可以有任意數量掛起連接

的您可以

  • 調查你連接的連接看看他們是否有已連接,或
  • 通過註冊OP_CONNECT將連接添加到選擇器。

在任何一種情況下,我建議撥打finishConnect()以確保它已準備好使用。

+0

非常感謝!我想我現在已經開始工作了,雖然我需要做更多的測試來確保。在昨天我沒有注意到的另一個(也是更廣泛使用的)Bitmessage客戶端發生了一些小的行爲變化,導致客戶端連接失敗的次數大大增加。我需要解決這個問題,以確保網絡代碼現在可以正常工作。 – Chris