Использование AsynchronousSocketChannel в Java - PullRequest
0 голосов
/ 24 мая 2018

При использовании AsynchronousSocketChannel в Java, как мы читаем () без вызова этих функций?Я проверяю чтение / запись с помощью netcat, но он должен быть асинхронным, поэтому я предполагаю, что вызов read () не завершится.Должен ли я использовать это по-другому?Если я использую read () в цикле, он выдает исключение «java.nio.channels.ReadPendingException», которое заставляет меня думать, что первое чтение () не было завершено, а второе попыталось прочитать () вместо первого чтения () ожидание завершения.

Я пытаюсь понять фрагмент, который я нашел на сайте, но я изменил его, чтобы сделать его проще:

public class EchoClient {

    public AsynchronousSocketChannel sockChannel;

    public EchoClient(String host, int port) throws IOException {
        sockChannel = AsynchronousSocketChannel.open();

        sockChannel.connect( new InetSocketAddress(host, port), sockChannel, new CompletionHandler<Void, AsynchronousSocketChannel >() {
            @Override
            public void completed(Void result, AsynchronousSocketChannel channel ) {
                System.out.println( "success");
            }

            @Override
            public void failed(Throwable exc, AsynchronousSocketChannel channel) {
                System.out.println( "failed to connect to server");
            }

        });
    }

    public void startRead() {
        final ByteBuffer buf = ByteBuffer.allocate(2048);

        sockChannel.read( buf, sockChannel, new CompletionHandler<Integer, AsynchronousSocketChannel>(){

            @Override
            public void completed(Integer result, AsynchronousSocketChannel channel) {
                //print the message
                System.out.println( "Read message:" + new String( buf.array()) );
            }

            @Override
            public void failed(Throwable exc, AsynchronousSocketChannel channel) {
            }

        });

    }

    public void write(final String message) {
        ByteBuffer buf = ByteBuffer.allocate(2048);
        buf.put(message.getBytes());
        buf.flip();
        sockChannel.write(buf, sockChannel, new CompletionHandler<Integer, AsynchronousSocketChannel >() {
            @Override
            public void completed(Integer result, AsynchronousSocketChannel channel ) {

            }

            @Override
            public void failed(Throwable exc, AsynchronousSocketChannel channel) {
                System.out.println( "Fail to write the message to server");
            }
        });
    }

}

Я вызываю его в main () следующим образом:

EchoClient echo = new EchoClient( "127.0.0.1", 3000, "echo test");
echo.startRead();
echo.write("hi");

Только с этим ^ клиент завершает работу, не удосужившись прочитать, если сервер еще ничего не отправил

1 Ответ

0 голосов
/ 25 мая 2018

Для чтения и записи необходимо поддерживать 3 переменные:

  • входная очередь буферов для чтения / записи

  • логическое значениефлаг, указывающий, что канал свободен (нет ожидающих чтения / записи сейчас).

  • выходная очередь буферов

, если канал занят,поместите буфер во входную очередь, иначе начните операцию ввода / вывода.Когда операция ввода / вывода завершается, он помещает свой буфер в очередь вывода, а затем проверяет очередь ввода.Если он пуст, для флага устанавливается значение true, в противном случае следующий буфер берется из входной очереди и операции перезапускаются.

...