gpt4 book ai didi

java - 使用 AsynchronousSocketChannel 时出现 ReadPendingException

转载 作者:太空宇宙 更新时间:2023-11-04 12:37:07 25 4
gpt4 key购买 nike

我一直在使用 AsychronousSockets,但在运行大负载时遇到了接收 ReadPendingException 的问题。

一些背景:我希望客户端异步向服务器发送消息,然后监听响应。

响应可以是 3 种类型之一,并且 AsynchronousSocketChannel 的读取需要预定大小的 ByteBuffer。

因此,我的解决方案是进行两次读取:一次读取首先接收消息类型(作为 4 个字节传入,一个 int),然后另一次读取将构造适当大小的字节缓冲区来处理消息的其余部分。

我认为这里的主要问题在于,当调用CompletetionHandler的complete方法时,并不一定意味着ByteBuffer的读取已完成。为了解决这个问题,我创建了一个 while 循环,它将读取直到 ByteBuffer 已满。

然而,在 while 循环中进行的读取似乎偶尔会与其他读取发生冲突,也就是当我收到 ReadPendingException 时。

基本骨架代码:

AsynchronousChannelGroup mThreadGroup= AsynchronousChannelGroup.withFixedThreadPool(100, Executors.defaultThreadFactory());
AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(mThreadGroup);
InetSocketAddress hostAddress = new InetSocketAddress("localhost", 12345);

// Connect to server
channel.connect(hostAddress, null, new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
// Write some message to server
ByteBuffer message = ...
channel.write(message, null, new CompletionHandler<Void, Void>() {

@Override
public void completed(Void result, Void attachment) {
// Now that we have sent the message, listen for a response type
ByteBuffer responseType = ...
channel.read(responseType, null, new CompletionHandler<Void, Void>() {

@Override
public void completed(Void result, Void attachment) {
// parse response type, do some other stuff...
// ...
// After other stuff, create new byte buffer for main message
ByteBuffer receiveMessage = ...
channel.read(receiveMessage, null, new CompletionHandler<Void, Void>() {

@Override
public void completed(Void result, Void attachment) {
// The read may not have been completed, so make sure that it is
while (receiveMessage.remaining() > 0) {
channel.read(receiveMessage);
}

// Handle receiveMessage...
}
@Override
public void failed(Throwable exc, Void attachment) {}
});
}
@Override
public void failed(Throwable exc, Void attachment) {}
});
}

public void failed(Throwable exc, Void attachment) {}
});
}

@Override
public void failed(Throwable exc, Void attachment) {}
});

所以我的问题有两个:

  1. 有没有办法让代码(如上所示)正常工作(也称为不再接收 ReadPendingException)?

  2. 是否有更好的方法来设置相同的功能?

提前感谢你们提供的任何可能的帮助。

最佳答案

您不应该在读取完成方法中循环,尤其是在不首先检查是否拥有所有数据的情况下。您应该首先检查是否已收到所需的所有数据,然后如果没有,请使用相同的完成方法发出再读一次。该过程将递归,直到满足第一个测试。

关于java - 使用 AsynchronousSocketChannel 时出现 ReadPendingException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37223693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com