首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java中使用AsynchronousSocketChannel

在Java中使用AsynchronousSocketChannel
EN

Stack Overflow用户
提问于 2018-05-24 05:13:52
回答 1查看 1.2K关注 0票数 0

在Java中使用AsynchronousSocketChannel时,如何在不调用这些函数的情况下读取()?我用netcat测试读/写,但它应该是异步的,所以我假设对read()的调用不会终止。我应该用不同的方式吗?如果在循环中使用read(),它会给出一个异常"java.nio.channels.ReadPendingException“,这使我认为第一个read()没有完成,但是第二个尝试读取()而不是等待完成的第一个read()。

我试图理解我在一个站点上找到的一个片段,但我修改了它,使其更简单:

代码语言:javascript
复制
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()中这样称呼它:

代码语言:javascript
复制
EchoClient echo = new EchoClient( "127.0.0.1", 3000, "echo test");
echo.startRead();
echo.write("hi");

只有这个^,如果服务器还没有发送任何内容,客户端就会终止,而不必费心阅读。

EN

回答 1

Stack Overflow用户

发布于 2018-05-24 22:31:19

无论是读还是写,都需要维护三个变量:

  • 用于读取/扭动的缓冲区的输入队列
  • 指示通道的布尔标志是空闲的(现在没有挂起的读/写)。
  • 缓冲区的输出队列

如果通道繁忙,将缓冲区放入输入队列,否则启动I/O操作。当I/O操作完成后,它将其缓冲区放在输出队列中,然后检查输入队列。如果为空,则将标志设置为true,否则将从输入队列中取出下一个缓冲区,并重新启动操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50501445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档