Исключение чтения и записи SocketChannel, когда клиент и сервер находятся на одном компьютере - PullRequest
0 голосов
/ 27 июня 2019

В моем коде есть структура, в которой я читаю и записываю ByteBuffers в канал сокета.В цикле while я вызываю методы onRead и onWrite.Когда я запускаю код, я получаю вывод типа «m; i1000; s1; t2000 ...».Все хорошо, когда Локальный адрес и Удаленный адрес - разные IP-адреса.Но когда хост для локального адреса и удаленного адреса совпадает, я получаю исключение на второй итерации цикла while, когда он пытается читать из канала.Но, тем не менее, это происходит не каждый раз, когда я запускаю код, несколько раз он запускается без проблем.

Я пытался приостановить программу с помощью Thread.sleep, думая, что это может произойти из-за высокой скорости выполнения операции на том же хосте.Кажется, это не влияет на случай.

Вот цикл while:

Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
    SelectionKey key = (SelectionKey) selectedKeys.next();
    selectedKeys.remove();

    if (key.isReadable()) {
        // Here the onRead method is called.
        // The first call has no problem 
        // but for the second iteration it throws an exception in the below code.
        if (!onRead(key)) {
            disconnect();
            continue;
        }
    }
}

Вот мой код, который я упоминаю:

private ByteBuffer in;
private SocketChannel channel;
in = ByteBuffer.allocateDirect(InputBufferSize); // InputBufferSize = 64*1024
in.order(ByteOrder.BIG_ENDIAN);
channel = SocketChannel.open();
channel.socket().setSoTimeout(ConnectTimeout); //ConnectTimeout = 5
channel.connect(activeAddr); // activeAddr = 127.0.0.1:29000
channel.configureBlocking(false);

private boolean onRead(SelectionKey key) throws IOException {
    int len = 0;
    try {
        // It tries to read ByteBuffer into len
        // The exception is thrown here.
        len = channel.read(in); 
    } catch (Exception e){
        System.err.println("Exception thrown!");
        // The variables have these values here:
        // in.remaining() = 65503
        // channel.isConnected() = true
        // channel.getLocalAddress() = 127.0.0.1:36000
        // channel.getRemoteAddress() = 127.0.0.1:29000
    }
    if (len <= 0 && in.remaining() < 1) {
        System.err.println("Read error");
        return false;
    }

    in.flip();

    if (!processMessages()) {
        return false;
    }
    in.compact();
    return true;
}

Ожидаемый вывод выглядит следующим образом:

Connecting to /127.0.0.1:29000
Connected to /127.0.0.1:29000
Login accepted. Session 20190621  . Seqno 1
m;i202006;s1;t154237.183;Dt20190620;
m;i202006;s1;t184512.573;Dt20190621;
End of session
Finished.

Вывод при выдаче исключения:

Connecting to /127.0.0.1:29000
Connected to /127.0.01:29000
Login accepted. Session 20190621  . Seqno 1
m;i202006;s1;t154237.183;Dt20190620;
Exception thrown!

Есть идеи, почему в указанном случае может возникать исключение?

...