首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于多个读写的单个java.nio AsynchronousSocketChannel实例

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

Stack Overflow用户
提问于 2017-05-29 08:08:16
回答 1查看 574关注 0票数 0

我在文档中读到AsynchronousSocketChannel是线程安全的,因此它的单个实例由多个线程共享是安全的,但是当我尝试实现这个单实例概念(在客户端应用程序中)时,我无法使用write()方法将数据发送到服务器。

以前,我成功地通过调用shutdownOutput()close() from channel after calling(byteBuffer,附件,附件)写入邮件从未到达服务器(我在服务器日志中看到它)。

我们是否需要关闭通道才能使消息到达服务器?我使用Spring boot来构建这个项目。

下面是我的代码:

代码语言:javascript
复制
@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();
  }
}

这是我的套接字连接完成处理程序类:

代码语言:javascript
复制
   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());
 }

 }

}

这是我的套接字写入完成处理程序类:

代码语言:javascript
复制
   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());

     }

   }
EN

回答 1

Stack Overflow用户

发布于 2017-05-29 08:37:43

如果服务器认为它没有接收到消息,当您之前关闭或关闭套接字时,它确实收到了消息,那么它一定是在尝试读取到流的末尾,并且阻塞或至少没有完成读取,因此永远不会记录任何内容。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44233163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档