zoukankan      html  css  js  c++  java
  • Socket设置超时时间

    主要有以下两种方式,我们来看一下
    方式1:

     Socket s=new Socket(); s.connect(new InetSocketAddress(host,port),10000); 
    方式2:

     Socket s=new Socket("127.0.0.1",8080); s.setSoTimeout(10000); 
    那么这两种方式设置的超时时间各自代表了什么意义呢?有什么区别呢?

    第1种方式
    我们先来看一下第1种方式,我们来测试一下:

    在 main 方法中我们创建 Socket 连接到

    ip :29.212.19.201,端口:2132

    public static void main(String[] args) {
    Socket socket = new Socket();
    SocketAddress endpoint = new InetSocketAddress("29.212.19.201", 2132);
    long timeMillis = System.currentTimeMillis();
    try {
    socket.connect(endpoint, 10000);
    } catch (IOException e) {
    e.printStackTrace();
    }
    System.out.println(System.currentTimeMillis()-timeMillis);
    System.out.println("end");
    }
    

      

    运行这段代码,控制台10秒之前没有任何信息输出,10秒后打印如下信息:

    10002
    java.net.SocketTimeoutException: connect timed out
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at com.wakling.cn.SocketSever.main(SocketSever.java:33)
    end
    

      

    可以看出,我们尝试连接到29.212.19.201:2132时,连接了10秒都没有连接上,于是就报了 java.net.SocketTimeoutException: connect timed out 的异常。

    解释一下,上述的 IP 是一个未知的 IP ,即我的 IP 在当前网络环境中访问不到这个 IP ,这样我们的这个 Socket 才会去一直尝试连接到此 IP 直到超时。如果 IP 是一个已知的 IP ,例如本地 127.0.0.1 加上一个未知的端口,那么此 Socket 连接会立马报错。

    另外,在不设置连接超时时间的情况下,Socket 默认大概是21s(测试了3次都是21020毫秒)连接超时。如下是不设置连接超时时间的代码:

     Socket socket = new Socket("29.212.19.201", 2132); 
    第2种方式
    然后我们来看一下第2种方式,这时候我们需要在我们本地写一套 Socket 服务以及客户端来模拟这个场景。

    我们让客户端设置 setSoTimeout 为10s,在服务端代码拿到客户端请求信息后,休眠10s后再处理客户端请求,返回响应。

    我们来看一下效果,关键代码如下:

    //服务端
    System.out.println("进入休眠,10s后醒来");
    Thread.sleep(10000);
    System.out.println("休眠结束");
    //返回响应
    OutputStream outputStream = socket.getOutputStream();// 获取一个输出流,向服务端发送信息
    PrintWriter printWriter = new PrintWriter(outputStream);// 将输出流包装成打印流
    printWriter.print("你好,服务端已接收到您的信息");
    printWriter.flush();
    ​
    //客户端
    Socket socket = new Socket("127.0.0.1",2132);
    socket.setSoTimeout(10000);//read的超时时间
    

      

    运行后,等待客户端输出,10s后客户端控制台输出信息如下:

    java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at com.wakling.cn.SocketClient.main(SocketClient.java:36)
    10020
    end
    

      

    这里10s后客户端报错 java.net.SocketTimeoutException: Read timed out 查看客户端控制台信息正常输出,即使客户端已报超时,服务端仍然继续往下走,只是客户端已经收不到服务端10s后发给自己的消息。

    另外经测试发现,服务端休眠很久很久,如500s,在客户端不设置 setSoTimeout 时,默认120s超时。

    区别和意义
    下面我们就来说一说二者的意义和区别。

    方式1是客户端与服务端进行连接的超时时间,即10秒内建立不了连接就报java.net.SocketTimeoutException: connect timed out 连接超时的异常。此时二者未建立连接,更别说服务端收到客户端的消息了。

    方式2是设置 inputStream.read() 方法的阻塞时间,即客户端发出请求后等待服务端返回响应的等待时长,超过这个时长将会引发 java.net.SocketTimeoutException: Read timed out 异常。此时二者正常建立连接,服务端接收到了客户端的请求。

    两种方式控制超时的侧重点不同,就像打电话一样,方法1是打电话10秒你不接电话我就挂了,方法2是打电话接通后,等你10秒不说话就挂,10秒后说不说话都不听了。

    原文链接:https://blog.csdn.net/ibigboy/article/details/93759809

  • 相关阅读:
    PGL:Paddle带你走进图学习
    Improving the way neural networks learn
    文本语义匹配Simnet模型
    图卷积神经网络(GCN)
    git revert
    vi/vim多行注释和取消注释、复制粘贴
    谷歌之多任务学习模型MMoE
    阿里CVR预估模型之ESMM
    知识图谱简介
    CTR预估--Deep Interest Network
  • 原文地址:https://www.cnblogs.com/LeeXiaoYang/p/11494691.html
Copyright © 2011-2022 走看看