Проблема Java с соединениями SocketChannel - PullRequest
0 голосов
/ 26 февраля 2011

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

У меня есть процесс, работающий на четырех виртуальных машинах 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 () &&.isConnectable () оба true, я думаю, что сервер для меня доступен для подключения.Я звоню

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

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

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

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

1 Ответ

0 голосов
/ 27 февраля 2011

Мы завернули попробовать / поймать вокруг 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-порта, которые нам понадобятся.

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

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

...