非阻塞式socket超时问题

发布于 2021-11-16 22:37:32 字数 2414 浏览 808 评论 1

请问:注释中的3处,是否可以设置超时时间?如果可以,各处的含义是怎么理解呢?那客户端超时如何设置呢?

服务端监听代码

public void start() throws IOException{
  try {
   s = Selector.open();
   ssc = ServerSocketChannel.open();
   ssc.configureBlocking(block);
   ssc.socket().bind(new InetSocketAddress(host, port),backlog);
//   ssc.socket().setSoTimeout(Constant.TIME_OUT_SERVER);
   status = Status.Running;
   logger.info("listening on "+port);
   ssc.register(s, SelectionKey.OP_ACCEPT);
   while (status != Status.Stoping && status != Status.Stoped){
    int count = s.select();
    if(count > 0){
     SocketChannel client = null;
     try {
      Iterator<SelectionKey> it = s.selectedKeys().iterator();
      while(it.hasNext()){
       SelectionKey key = it.next();
       it.remove();
       if(key.isAcceptable()){
        if(current.incrementAndGet() < maxClient){
         client = (SocketChannel)ssc.accept();
//         client.socket().setSoTimeout(Constant.TIME_OUT_CLIENT);
         client.configureBlocking(false);
         connected(client,s);
        }
       }
       if (key.isReadable()) {
        client = (SocketChannel)key.channel();
//        client.socket().setSoTimeout(Constant.TIME_OUT_CLIENT);
        client.configureBlocking(false);
        recevieData(client,s);
       }
      }
     } catch (IOException e) {
      logger.error("Error ",e);
      if(client != null){
       try {
        client.close();
       } catch (Exception e2) {
       }
       current.decrementAndGet();
      }
     }
    }
   }
  } finally {
   if(s != null){
    try {
     s.close();
    } catch (IOException e) {
    }
   }
   if(ssc != null){
    try {
     ssc.close();
    } catch (IOException e) {
    }
   }
  }
 }

客户端连接代码

public boolean connect() throws IOException{
  if(keepAlive  && s != null && s.isConnected() && state != TransState.Stoped){
   return true;
  }
  if(s == null || !s.isOpen() || state == TransState.Stoped){
   s = SocketChannel.open();
  }
  if(!s.isConnected() || state == TransState.Stoped){
   s.connect(new InetSocketAddress(host, port));
//   s.socket().connect(new InetSocketAddress(host, port),Constant.TIME_OUT_CLIENT);
  }
//  s.socket().setSoTimeout(Constant.TIME_OUT_CLIENT);
  return true;
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷弦 2021-11-18 17:05:58

setSoTimeout:

With this option set to a non-zero timeout, a call to accept() for this ServerSocket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the ServerSocket is still valid. The option must be enabled prior to entering the blocking operation to have effect.

我觉得吧,服务器端设置第一个或者第二个二选一即可了,第二个的作用就是在轮询的时候,如果有连接,防止超时。而第一个就好比是个整体的设置,多有的连接都必须控制在这个时间内。第三个也差不多,都是key's channel is ready for reading的时候然后设置超时。

至于客户端,原理跟服务器端一样的。

随便一说,不知道对不对,呵呵。你可以拿代码测一下。。。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文