用于多次读写的java.nio AsynchronousSocketChannel的单个实例

时间:2017-05-29 00:08:16

标签: java nio

正如我从文档中读到的那样 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());
 }

 }

}

1 个答案:

答案 0 :(得分:0)

如果服务器认为它没有收到消息,并且它在您之前关闭或关闭套接字时发生了,它必须尝试读取到流的末尾,并阻止或至少不完成它读取,所以从不记录任何东西。

为什么将多个线程与异步I / O一起使用,或者实际上与任何套接字一起使用仍然是个谜。