java - AsynchronousSocketChannel#read 永远不会完成。

标签 java

我正在试验 NIO2 并遇到了问题。

这是我使用的代码:

ByteBuffer buffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
    channel.read(buffer, null, new CompletionHandler<Integer, Object>() {
        @Override
        public void completed(Integer result, Object attachment) {
            Packet packet = new Packet(buffer.getInt(), buffer);
            PacketHandler handler = PacketHandler.forOpcode(packet.getOpcode());
            if(!Objects.isNull(handler)) {
                handler.handle(channel, packet);
            } else {
                System.out.println("Unexpected opcode received from client. Opcode: " + packet.getOpcode());
            }
        }

        @Override
        public void failed(Throwable exc, Object attachment) {
            System.out.println("DEBUG A");
            exc.printStackTrace();
        }
    });

问题是无论我向服务器发送什么,它都不会完成。出于测试目的,我设置了一个非常扁平格式的登录数据包,并通过客户端发送此数据:

    ByteBuffer buffer = ByteBuffer.allocate(28);
    buffer.putInt(1); //opcode
    ByteBufferUtils.putString(buffer, "admin");
    ByteBufferUtils.putString(buffer, "admin");
    channel.write(buffer);

即使客户端写入数据,服务器也永远不会完成读取。我还确保 (DEFAULT_BUFFER_SIZE) 等于发送的缓冲区大小以查看是否是问题所在,但功能仍然没有任何变化。

每当我断开客户端连接时(目前正在使用一个线程来保持它的 Activity 状态,绝对没有任何原因)我从 #failed

得到以下打印堆栈跟踪
java.io.IOException: The specified network name is no longer available.
at sun.nio.ch.Iocp.translateErrorToIOException(Iocp.java:309)
at sun.nio.ch.Iocp.access$700(Iocp.java:46)
at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:399)
at java.lang.Thread.run(Thread.java:745)

最佳答案

你没有发送任何东西。在调用 write() 之前,您需要先flip() 缓冲区,之后再调用 compact()

关于java - AsynchronousSocketChannel#read 永远不会完成。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30294196/

相关文章:

java - 如何在 Java 中传递嵌套的 Scala 对象引用?

java - Catmull Rom 样条实现 (LibGDX)

java - 排除的 Artifact 显示在依赖项 :tree 中

java - 在 Java 中使用大量对象是否存在性能问题

java - 在 Apache HTTP Server 中调用 Java 程序

java - 使用 Mono 而不是 Java 的主要好处是什么?

java - 如何在单个 Controller 中制作多个@PatchMapping?

不同操作系统下的 Java 程序效率

java - 让计时器从代码中的特定点开始

java - 拦截器没有被调用