正如我从文档中读到的那样 AsynchronousSocketChannel 是线程安全的,因此多个线程共享它的单个实例是安全的,但是当我尝试实现这个单实例概念时(在客户端)应用程序)我没有使用 write()方法向服务器发送数据(之前我通过调用 shutdownOutPut()或 close()成功完成此操作调用 write(byteBuffer,attachment,completionHandler)后从通道调用。但是当我只想使用单个实例而不调用 close()或 shutdownOutput()时,消息永远不会到达服务器(我从服务器日志中看到它)。我们是否需要关闭频道以使消息到达服务器。我使用spring boot来构建这个项目,希望得到一些帮助
这是我的代码:
bear
这是我的套接字连接完成处理程序类:
@Component
public class AgentStatusService {
private static final Logger log =
LoggerFactory.getLogger(AgentStatusService.class);
@Autowired
private SocketAddress serverAddress;
@Autowired
private AsynchronousSocketChannel channel;
public void consumeMessage() throws IOException {
try {
log.info("trying to connect to {}", serverAddress.toString());
channel.connect(serverAddress, channel, new SocketConnectCompletionHandler());
log.info("success connect to {}", channel.getRemoteAddress());
} catch (final AlreadyConnectedException ex) {
final ByteBuffer writeBuffer = ByteBuffer.wrap("__POP ".getBytes());
final Map<String, Object> attachm`enter code here`ent = new HashMap<>();
attachment.put("buffer", writeBuffer);
attachment.put("channel", channel);
writeBuffer.flip();
channel.write(writeBuffer, attachment, new SocketWriteCompletionHandler());
}
} catch (final Exception e) {
log.error("an error occured with message : {}", e.getMessage());
e.printStackTrace();
}
}
}
这是我的套接字写入完成处理程序类:
public class SocketConnectCompletionHandler
implements CompletionHandler<Void, AsynchronousSocketChannel> {
private static Logger log =
LoggerFactory.getLogger(SocketConnectCompletionHandler.class);
@Override
public void completed(Void result, AsynchronousSocketChannel channel) {
try {
log.info("connection to {} established", channel.getRemoteAddress());
final ByteBuffer writeBuffer = ByteBuffer.wrap("__POP ".getBytes());
final Map<String, Object> attachment = new HashMap<>();
attachment.put("buffer", writeBuffer);
attachment.put("channel", channel);
writeBuffer.flip();
channel.write(writeBuffer, attachment, new
SocketWriteCompletionHandler());
} catch (final IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, AsynchronousSocketChannel attachment) {
exc.printStackTrace();
try {
log.error("connection to {} was failed", attachment.getRemoteAddress());
} catch (final Exception e) {
log.error("error occured with message : {}", e.getCause());
}
}
}
答案 0 :(得分:0)
如果服务器认为它没有收到消息,并且它在您之前关闭或关闭套接字时发生了,它必须尝试读取到流的末尾,并阻止或至少不完成它读取,所以从不记录任何东西。
为什么将多个线程与异步I / O一起使用,或者实际上与任何套接字一起使用仍然是个谜。