你知道在 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种方式

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

在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 outat 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 outat 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超时。
对于 setSoTimeout 方法官方给的解释是这样的,我不知道超时时间设置为0是否真的为无穷大超时,感兴趣的可以试一下。

setSoTimeout

public void setSoTimeout(int timeout)

   throws SocketException启用/禁用带有指定超时值

   SO_TIMEOUT,以毫秒为单位。将此选项设为非零的超时值时,

      在与此 Socket 关联的 InputStream 上调用 read() 将只阻塞此时间长度

      如果超过超时值,将引发 java.net.SocketTimeoutException,虽然 Socket 仍旧有效。

      选项必须在进入阻塞操作前被启用才能生效。

   超时值必须是 > 0 的数。超时值为 0 被解释为无穷大超时值

参数:timeout - 指定的以毫秒为单位的超时值。

抛出:SocketException - 如果底层协议出现错误,例如 TCP 错误。

从以下版本开始:JDK 1.1

另请参见:getSoTimeout()

区别和意义

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

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

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

合理设置超时时间对增加程序的吞吐量和加强程序的健壮性有较为重大的意义。

两种方式控制超时的侧重点不同,就像女朋友给你打电话一样,她是有小脾气的。如果她按方法1对待你,那就是拨出去电话10秒内你不接电话她就挂了,如果她按方法2,那就是打电话接通后,假如你正在忙她就等你10秒,10秒内不说话就挂,10秒后说不说话她都听不到了,你就悲催了。

转载请注明出处

转载于:https://www.cnblogs.com/ibigboy/p/11089324.html

Socket超时时间设置相关推荐

  1. Python 技术篇-全局与当前socket超时连接时间设置方法实例演示,查看socket超时连接时间

    socket.setdefaulttimeout() 方法用于设置全局socket超时连接时间. settimeout()方法用于设置全局socket超时连接时间. 代码演示: import sock ...

  2. 修改服务器超时时间,服务器超时时间设置

    服务器超时时间设置 内容精选 换一换 在压测过程中能够提供自身性能数据的施压目标机器.管理执行机的节点.CPTS为用户的测试工程提供管理能力,事务.压测任务.测试报告的内容在同一个测试工程内共享复用, ...

  3. 联众服务器超时中断,http连接中客户端中断了请求,服务端会中断执行吗?超时时间设置?...

    由于http是基于tcp的,在tcp中,客户端中断了连接,服务端是无法感知的,只能通过发心跳包来检测,而显然我们的nginx是没有发心跳包的,所以,包括nginx,php-fpm都是不知道客户端已断开 ...

  4. 聊聊ribbon的超时时间设置

    序 本文主要研究一下ribbon的超时时间设置 配置 实例 ribbon:ReadTimeout: 10000ConnectTimeout: 10000MaxAutoRetries: 0MaxAuto ...

  5. Modbus 超时时间设置

    原文链接:https://blog.csdn.net/sunxboy/java/article/details/84499791 Modbus通讯时,需要连续读取多个现场设备的数据,虽然也编写了Mod ...

  6. TCP 超时时间设置过长或 MTU 设置不合理会导致网络速度变慢吗

    是的,TCP 超时时间设置过长或 MTU 设置不合理都可能导致网络速度变慢. TCP 超时时间是指在发送数据之后,如果没有收到对端的应答,就会在超时时间后再次发送数据.如果超时时间设置过长,会导致发送 ...

  7. 服务器时间修改连接超时时间,服务器设置网络连接超时时间设置

    服务器设置网络连接超时时间设置 内容精选 换一换 有以下几种现象:将制作好的SD卡插入开发者板并上电后,开发者板LED1与LED2灯状态信息异常.将制作好的SD卡插入开发者板,并通过USB方式连接Ub ...

  8. linux socket默认超时时间设置,Socket中如何设置连接超时 (转)

    Socket中如何设置连接超时 (转) Socket中如何设置连接超时 AntGhazi/2001.12.14 主页:antghazi.yeah 把CSDN与中文翻了底朝天,也没找到如何设置socke ...

  9. Feign Client的各种超时时间设置

    在Spring Cloud微服务架构中,大部分公司都是利用Open Feign进行服务间的调用,而比较简单的业务使用默认配置是不会有多大问题的,但是如果是业务比较复杂,服务要进行比较繁杂的业务计算,那 ...

最新文章

  1. Mysql 架构及优化之-定时计划任务
  2. cassandra hbase_为什么选择Cassandra
  3. 格伦布编码——rice编码无非是golomb编码M为2^x的特例
  4. 在stringgrid的drawcell事件处理过程中,给单元格赋值时,要用textout输出,不要像一般给cell[i,j]赋值那样。
  5. jQuery之高级选择器
  6. 二级指针与指针数组的关系
  7. 使用FormData对象
  8. 22. GD32F103C8T6入门教程-RTC的时间设置、读取日历转换
  9. 【js高级程序设计】迭代器
  10. swift UI专项训练19 TextView 多行文本
  11. 2021-09-08173. 二叉搜索树迭代器 栈
  12. Linux下硬盘分区详解
  13. bilibili开源弹幕库UML类图
  14. 使用tushare计算北上资金持仓成本
  15. html轮播图点击图片放大,jq点击图片 放大轮播
  16. 简单易懂的并查集算法以及并查集实战演练
  17. 用Matlab的.m脚本文件处理实验室数据
  18. 项目管理工具dhtmlxGantt甘特图入门教程(十五):从MS项目导入/导出(上)
  19. 【计算机·科技】互联网的黑科技来啦
  20. 最新『资源分享』IT视频教程

热门文章

  1. Eclipse:An internal error occurred during: Building workspace. GC overhead limit exceeded
  2. hibernate的数据关联映射
  3. WCF 第十二章 对等网 System.Net.PeerToPeer.Collaboration
  4. ES6——变量的解构赋值
  5. (进阶)LeetCode(258)——各位相加(JavaScript)
  6. react-native---配置reactnative报红,run-Android时候报错unable to load script from assets 'index.android.bundl
  7. 点餐系统的设计(一)
  8. 听说社保不能补缴了,像我们这种没缴社保的打工者,该怎么办?
  9. 你在微信漂流瓶里遇到过哪些有意思的人和事?
  10. 后起之秀,《你好,李焕英》,票房已过十个亿和唐探三哪个好?