Socket超时时间设置
你知道在 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 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超时。
对于 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秒后说不说话她都听不到了,你就悲催了。
转载请注明出处
Socket超时时间设置的更多相关文章
- unigui session超时时间设置
unigui session超时时间设置 默认的SESSION超时时间是10分钟. 网络 SOCKET 程序,像 数据库,中间件,UNIGUI等...为了防止过多的僵死连接卡死服务端,服务端都会主动踢 ...
- (转)nginx限制上传大小和超时时间设置说明/php限制上传大小
nginx限制上传大小和超时时间设置说明/php限制上传大小 原文:http://www.cnblogs.com/kevingrace/p/6093671.html 现象说明:在服务器上部署了一套后台 ...
- session超时时间设置方法
session超时时间设置方法 由于session值之前没有设置,以至于刚登录的网站,不到一分钟就超时了,总结了一下,原来是session过期的原因,以下是设置session时间的3个方法: 1. 在 ...
- GS 服务器超时时间设置
工作中 遇到一个超时的问题 与徐庆同学沟通后 了解了下超时时间设置的地方 1.web.congfig问题: 常规路径 C:\Program Files\GenerSoft\bscw_local\web ...
- 接口调试工具ApiPost的发送超时时间设置方法
有部分使用ApiPost的同学反应:发送接口调试时,响应超时时间设置的太短导致接口访问失败,怎么设置呢? 就连百度也有很多人在搜: 今天就来说一说. ApiPost简介: ApiPost是一个支持团队 ...
- MYSQL的数据连接超时时间设置
大规模多线程操作事务的时候,有时候打开一个链接,会进行等待,这时候如果数据库的超时时间设置的过短,就可能会出现,数据链接自动被释放,当然设置过大也不好,慢SQL或其他因素引起的链接过长,导致整个系统被 ...
- 【Hadoop】Hadoop DataNode节点超时时间设置
hadoop datanode节点超时时间设置 datanode进程死亡或者网络故障造成datanode无法与namenode通信,namenode不会立即把该节点判定为死亡,要经过一段时间,这段时间 ...
- session的工作原理、django的超时时间设置及session过期判断
1.session原理 cookie是保存在用户浏览器端的键值对 session是保存在服务器端的键值对 session服务端中存在的数据为: session = { 随机字符串1:{ 用户1的相关信 ...
- httpclient超时时间设置及代理设置
超时时间 设置HttpClient的超时时间,非常有必要性,因为httpclient 默认超时时间很长,自己可以测试一下是多久,设置超时时间否则会影响自己系统的业务逻辑,例如阻塞系统,影响系统的吞吐量 ...
随机推荐
- 123: The filename, directory name, or volume label syntax is incorrect今天玩nginx的时候报错
今天在win下玩nginx的时候 提示500错误 看了下nginx的logs 提示 123: The filename, directory name, or volume label syntax ...
- oracle学习笔记(十三) 查询练习(三) 子查询查询
子查询练习 create table empployee_demo( empno number(4) not null primary key, --员工编号,主键 ename varchar2(10 ...
- \" 转义字符, \a系统警报,逐字字符串(verbatim string)
string str="The key factors are \"focus\" and \"perseverance\""; strin ...
- go-数据结构
数据结构 数据结构(算法)的介绍 数据结构的介绍 1) 数据结构是一门研究算法的学科,只从有了编程语言也就有了数据结构.学好数据结构可以编写 出更加漂亮,更加有效率的代码. 2) 要学习好数据结构就要 ...
- Tomcat8史上最全优化实践
Tomcat8史上最全优化实践 1.Tomcat8优化 1.1.Tomcat配置优化 1.1.1.部署安装tomcat8 1.1.2 禁用AJP连接 1.1.3.执行器(线程池) 1.1.4 3种运行 ...
- XSS攻击(跨站脚本攻击)
一.什么是XSS?怎么发生的? XSS(Cross site scripting)全称为跨站脚本攻击,是web程序中最常见的漏洞.指攻击者在网页中嵌入客户端脚本(例如Javascript),当用户浏览 ...
- Unity Pixel 人物设计(1)
草稿: 目前进度:
- js 时间戳转化为时间
// 时间戳转为时间 bb="xxxx"://时间戳 var date = new Date(bb); Y = date.getFullYear() + '-'; M = (dat ...
- rsync 未授权访问漏洞
rsync rsync,remote synchronize顾名思意就知道它是一款实现远程同步功能的软件,它在同步文件的同时,可以保持原来文件的权限.时间.软硬链接等附加信息. rsync是用 &qu ...
- SparkSql 整合 Hive
SparkSql整合Hive 需要Hive的元数据,hive的元数据存储在Mysql里,sparkSql替换了yarn,不需要启动yarn,需要启动hdfs 首先你得有hive,然后你得有spark, ...