Проблемы Java с подключениями SocketChannel

Это задание класса, поэтому мне нужны подсказки больше, чем ответы.

У меня есть процесс, работающий на четырех виртуальных машинах Linux. Каждый процесс общается с двумя своими соседями. Каждый процесс использует

server = ServerSocketChannel.open()
server.configureBlocking(false)
server.socket().bind(new InetSocketAddress(port))
server.register(selector, SelectionKey.OP_ACCEPT)

При запуске процесс A ни к кому не пытается подключиться. Процесс B делает

SocketChannel SC = SocketChannel.open()
SC.configureBlocking( false )
SC.connect(new INetSocketAddress( A-machine, A-port )
SC.register( selector, SC.validOps())

Процесс C делает то же самое с B; и D с C.

Затем я вызываю selector.select и перебираю все selectedKeys. Когда я вижу key.isValid () && key.isAcceptable () как true, я думаю, что сокет пытается подключиться ко мне, и я вызываю

SocketChannel client = server.accept()
client.configureBlocking(false)
client.register(selector, client.validOps() )

Когда я вижу, что key.isValid () && key.isConnectable () оба являются истинными, я думаю, что мне доступен сервер, к которому я могу подключиться. Я звоню

SocketChannel connectingChannel = (SocketChannel)key.channel()
connectingChannel.finishConnect()

Когда я вижу key.isValid () && key.isReadable (), я читаю полученное сообщение.

Этот процесс работает ПОКОЛЬКО Я ЗАПУСКАЮ ПРОЦЕССЫ В ПОРЯДКЕ: A, B, C, D. Если я запускаю только B, он терпит неудачу в инструкции finishConnect.

Я читал документы, в которых isConnectable проверяет, завершил ли канал этого ключа операцию подключения к сокету или не удалось ее завершить. Как isConnectable может быть истинным, и я получаю сбой на finishConnect?


person Kelly Cline    schedule 26.02.2011    source источник


Ответы (1)


Мы обернули try / catch вокруг finishConnect. Внутри улова мы вызвали отмену для текущего SelectionKey, а затем вызвали метод, который попытался установить соединение (второй фрагмент в исходном описании проблемы):

SocketChannel SC = SocketChannel.open()
SC.configureBlocking( false )
SC.connect(new INetSocketAddress( A-machine, A-port )
SC.register( selector, SC.validOps())

Предвидя, что нам придется это сделать, мы добавили код для хранения взаимосвязи между SC, A-машиной и A-портом, чтобы они были у нас при повторной попытке. Итак, в уловке перед отменой мы использовали отказавший SocketChannel для поиска необходимых данных A-машины и A-порта, которые нам понадобились.

В конце концов, сервер подключился, и это соединение было успешно установлено.

Я знаю, что это ответ, а не намек, но это было наше задание :)

person Kelly Cline    schedule 27.02.2011