Java разъемы NIO - отличительные guish клиенты - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть три процесса, обменивающихся между собой 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

Это последний шаг, доставляющий мне проблемы.

  1. Как отличить guish, какой клиент отправил мне сообщение ?

Это более сложный вопрос, чем кажется, что сначала вы должны понять сообщение. Позвольте мне объяснить и исправить меня, если я ошибаюсь.

Когда вы читаете, вы читаете сообщение ключа в буфер. Казалось логичным, что два процесса, отправляющие мне сообщение, сгенерируют два ключа, поэтому при чтении каждого ключа в буфер проблем не возникнет, но я заметил, что при чтении ключа оба сообщения читаются в буфер одно после другие, такие как [Message1Message2]. Итак, чтобы выяснить сообщение, я добавил «#» в конце каждого сообщения, а затем просто разделил его (грязный, но работал).

С этим [Message1Message2] стало [Message1 # Message2 #] а затем [Message1] и [Message2], так что у нас есть сообщения. Как я уже сказал, я понятия не имею, почему два разных сообщения, которые должны иметь два разных ключа, читаются с одного ключа. Наконец, как я спросил до и после разделения сообщений, какой клиент отправил мне какое сообщение?

Предполагая, что я знаю, на какой процесс я должен ответить с помощью ACK, я столкнулся с проблемой при переключении метода записи на ключ и отправке ACK.

Как работают ключи, мне трудно как вы могли догадаться. Любой совет?

...