2016-08-27 1 views
0

Я использую Java NIO для однорангового протокола и вам необходимо создать много одновременных соединений, из-за которых многие не будут работать. К сожалению, кажется, что мне нужно подождать, пока соединение будет установлено до создания следующего, иначе я получу «BindException: не могу назначить запрошенный адрес: connect». Кто-нибудь есть идея, как это исправить?Создайте несколько исходящих подключений одновременно в 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

Никогда не ловите исключения и не обрабатывайте его. Как и ваше noroutetohostexception – Jens

+0

Вы не можете использовать соединение до его завершения, но вы можете иметь любое количество ожидающих подключения. –

+0

@Jens: Я почти согласен, но я ожидаю, что нет пути к некоторым хостам, и нечего делать, кроме попытки следующего. Ожидается и другое (происходит при выключении), но я могу зарегистрироваться, если это произойдет в других случаях. – Chris

ответ

0

Вы не можете использовать соединение до его завершения соединения, но вы можете иметь любое количество ожидающих соединений

Вы можете

  • опроса вы подключение соединения, чтобы увидеть, если они имеют подключен еще, или
  • добавьте подключение к селектору, зарегистрировав OP_CONNECT.

В любом случае я предлагаю позвонить finishConnect(), чтобы убедиться, что он готов к использованию.

+0

Спасибо большое! Я думаю, что сейчас у меня это работает, хотя мне нужно сделать еще несколько тестов, чтобы убедиться. В другом (и более широко используемом) клиенте Bitmessage было небольшое изменение поведения, которое я не заметил до вчерашнего дня, что привело к значительно более неудачным подключениям в моем клиенте. Мне нужно исправить это, чтобы убедиться, что сетевой код теперь работает правильно. – Chris

Смежные вопросы