У меня есть три процесса, обменивающихся между собой AKA, каждый из которых выполняет и сервер, и клиент в одном потоке.
Пока что каждый из них настраивает сервер:
private void setServer() throws IOException {
// Create a new selector
selector = Selector.open();
// Create a new non-blocking server socket channel
serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
// Bind the server socket to the specified address and port
serverChannel.bind(new InetSocketAddress("localhost", port));
// Register the server socket channel, indicating an interest in
// accepting new connections
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
}
и клиент :
firstClient = SocketChannel.open(new InetSocketAddress("localhost", firstPort));
secondClient = SocketChannel.open(new InetSocketAddress("localhost", secondPort));
Пока все хорошо. Теперь мы получаем обычную структуру для обработки передачи данных:
//writeMessage();
while (true) {
try {
// Wait for an event one of the registered channels
selector.select();
// Iterate over the set of keys for which events are available
Iterator selectedKeys = selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = (SelectionKey) selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
}
// Check if they key is ready to accept a new socket connection
if (key.isAcceptable()) {
keyAccept(key);
} else if (key.isReadable()){
keyRead(key);
} else if (key.isWritable()){
keyWrite(key);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Хорошо, поэтому каждый процесс получает два соединения от других процессов, которые обрабатываются двумя разными ключами в методе keyAccept.
ВЫПУСК:
Теперь каждый процесс должен отправить сообщение другим, а также ответить ACK на сообщения, полученные другими процессами.
Если мы раскомментируем метод writeMessage (), выполнение должно go следующим образом:
Сервер настроен -> Клиент настроен -> Отправлять сообщения другим процессам через клиент -> Запросить мои ключи для событий (здесь будут выполняться два keyAccept и два keyRead правильно) -> Ответить на каждое сообщение, полученное с помощью ACK
Это последний шаг, доставляющий мне проблемы.
- Как отличить guish, какой клиент отправил мне сообщение ?
Это более сложный вопрос, чем кажется, что сначала вы должны понять сообщение. Позвольте мне объяснить и исправить меня, если я ошибаюсь.
Когда вы читаете, вы читаете сообщение ключа в буфер. Казалось логичным, что два процесса, отправляющие мне сообщение, сгенерируют два ключа, поэтому при чтении каждого ключа в буфер проблем не возникнет, но я заметил, что при чтении ключа оба сообщения читаются в буфер одно после другие, такие как [Message1Message2]. Итак, чтобы выяснить сообщение, я добавил «#» в конце каждого сообщения, а затем просто разделил его (грязный, но работал).
С этим [Message1Message2] стало [Message1 # Message2 #] а затем [Message1] и [Message2], так что у нас есть сообщения. Как я уже сказал, я понятия не имею, почему два разных сообщения, которые должны иметь два разных ключа, читаются с одного ключа. Наконец, как я спросил до и после разделения сообщений, какой клиент отправил мне какое сообщение?
Предполагая, что я знаю, на какой процесс я должен ответить с помощью ACK, я столкнулся с проблемой при переключении метода записи на ключ и отправке ACK.
Как работают ключи, мне трудно как вы могли догадаться. Любой совет?