在Java中使用AsynchronousSocketChannel时,如何在不调用这些函数的情况下read()?我用netcat测试读/写,但它应该是异步的,所以我假设对read()的调用不会终止。我应该以不同的方式使用它吗?如果我在循环中使用read(),它会给出异常" java.nio.channels.ReadPendingException"这让我觉得第一个read()没有完成,但是第二个尝试read()而不是第一个read()等待完成。
我正在尝试了解我在网站上找到的代码片段,但我将其修改为更简单:
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");
只有这个^,如果服务器还没有发送任何内容,客户端会终止而无需阅读
答案 0 :(得分:0)
对于阅读和写作,您需要维护3个变量:
用于读取/扭动的缓冲区的输入队列
一个布尔标志,表示该频道是免费的(现在没有待处理的读/写)。
缓冲区的输出队列
如果通道忙,则将缓冲区放入输入队列,否则启动I / O操作。当I / O操作完成时,它将其缓冲区放在输出队列中,然后检查输入队列。如果为空,则将该标志设置为true,否则从输入队列中取出下一个缓冲区并重新开始操作。