我在文档中读到AsynchronousSocketChannel是线程安全的,因此它的单个实例由多个线程共享是安全的,但是当我尝试实现这个单实例概念(在客户端应用程序中)时,我无法使用write()方法将数据发送到服务器。
以前,我成功地通过调用shutdownOutput()或close() from channel after calling(byteBuffer,附件,附件)写入邮件从未到达服务器(我在服务器日志中看到它)。
我们是否需要关闭通道才能使消息到达服务器?我使用Spring boot来构建这个项目。
下面是我的代码:
@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());
}
}
}这是我的套接字写入完成处理程序类:
public class SocketWriteCompletionHandler
implements CompletionHandler<Integer, Map<String, Object>> {
private static final Logger log =
LoggerFactory.getLogger(SocketWriteCompletionHandler.class);
@Override
public void completed(Integer result, Map<String, Object> attachment) {
try {
final AsynchronousSocketChannel channel =
(AsynchronousSocketChannel) attachment.get("channel");
final ByteBuffer buffer = (ByteBuffer) attachment.get("buffer");
log.info("write {} request to : {}", new String(buffer.array()),
channel.getRemoteAddress());
buffer.clear();
readResponse(channel, buffer);
} catch (final Exception ex) {
ex.printStackTrace();
log.error("an error occured with message : {}", ex.getMessage());
}
}
@Override
public void failed(Throwable exc, Map<String, Object> attachment) {
log.error("an error occured : {}", exc.getMessage());
}
public void readResponse(AsynchronousSocketChannel channel, ByteBuffer
writeBuffer) {
final ByteBuffer readBuffer = ByteBuffer.allocate(2 * 1024);
final Map<String, Object> attachment = new HashMap<>();
attachment.put("writeBuffer", writeBuffer);
attachment.put("readBuffer", readBuffer);
attachment.put("channel", channel);
readBuffer.flip();
channel.read(readBuffer, attachment, new
SocketReadCompletionHandler());
}
}发布于 2017-05-29 08:37:43
如果服务器认为它没有接收到消息,当您之前关闭或关闭套接字时,它确实收到了消息,那么它一定是在尝试读取到流的末尾,并且阻塞或至少没有完成读取,因此永远不会记录任何内容。
为什么您要将多线程与异步I/O或任何套接字一起使用,这仍然是一个谜。
https://stackoverflow.com/questions/44233163
复制相似问题