返回顶部
首页 > 资讯 > 后端开发 > Python >JavaSocket设置timeout的几种常用方式说明
  • 548
分享到

JavaSocket设置timeout的几种常用方式说明

JavaSocketSocket设置timeoutJavaSocket设置timeout 2022-11-13 19:11:01 548人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录1. Socket timeout1.1 建立连接connect timeout1.2 读取数据so timeout1.3 小结2. 使用案例2.1 Mysql jdbc tim

Java的网络编程Socket常常用于各种网络工具,比如数据库的jdbc客户端,Redis客户端jedis,各种rpc工具java客户端,这其中存在一些参数来配置timeout,但是之前一直对timeout的理解还不清晰,所以会导致使用这些网络工具的时候有点迷茫。在此做个总结。

1. Socket timeout

Java socket有如下两种timeout:

  • 建立连接timeout,暂时就叫 connect timeout
  • 读取数据timeout,暂时就叫so timeout 

1.1 建立连接connect timeout

当不设置该参数时,指客户端请求和服务端建立tcp连接时,会一直阻塞直到连接建立成功,或抛异常。当设置了connectTimeout, 客户端请求和服务端建立连接时,阻塞时间超过connectTimeout时,就会抛出异常java.net.ConnectException: Connection timed out: connect。

我们看如下精简后的代码,首先是服务端:

serverSocket = new ServerSocket(8080); 
Socket socket = serverSocket.accept(); 

服务端开启ServerSocket监听8080端口,再看客户端:

socket = new Socket(); 
socket.connect(new InetSocketAddress("localhost", 8080)); 
System.out.println("Connected.");

打印“Connected.”,修改客户端代码中的主机名为一个不存在的主机:

socket = new Socket(); 
long t1 = 0; 
try { 
t1 = System.currentTimeMillis(); 
socket.connect(new InetSocketAddress("www.ss.ssss", 8080)); 
} catch (IOException e) { 
long t2 = System.currentTimeMillis(); 
e.printStackTrace(); 
System.out.println("Connect failed, take time -> " + (t2 - t1) + "ms."); 
}

抛出异常:java.net.ConnectException: Connection timed out: connect,并打印:Connect failed, take time -> 18532ms. 也就是当未设置connect timeout时,connect方法会阻塞直到底层异常抛出。经过测试socket有个默认的超时时间,大概在20秒左右(测试的值,不一定准确,待研究JVM源码)。

下面我们来设置connect timeout,再看看效果:

socket = new Socket(); 
long t1 = 0; 
try { 
t1 = System.currentTimeMillis(); 
// 设置connect timeout 为2000毫秒 
socket.connect(new InetSocketAddress("www.ss.ssss", 8080), 2000); 
} catch (IOException e) { 
long t2 = System.currentTimeMillis(); 
e.printStackTrace(); 
System.out.println("Connect failed, take time -> " + (t2 - t1) + "ms."); 
}

抛出异常:java.net.SocketTimeoutException: connect timed out,并打印:Connect failed, take time -> 2014ms. 这里就是connect timeout发挥作用了。

1.2 读取数据so timeout

先看下jdk源码注释:

Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds.  

With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time.  

If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect.

The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.    

这个参数通过socket.setSoTimeout(int timeout)方法设置,可以看出它的意思是,socket关联的InputStream的read()方法会阻塞,直到超过设置的so timeout,就会抛出SocketTimeoutException。

当不设置这个参数时,默认值为无穷大,即InputStream的read方法会一直阻塞下去,除非连接断开。

下面通过代码来看下效果:

服务端代码:

serverSocket = new ServerSocket(8080); 
Socket socket = serverSocket.accept(); 

服务端只接受socket但不发送任何数据给客户端。客户端代码:

socket = new Socket(); 
socket.connect(new InetSocketAddress("localhost", 8080)); 
System.out.println("Connected."); 
in = socket.getInputStream(); 
System.out.println("reading..."); 
in.read(); 
System.out.println("read end");

客户端建立连接就开始读取InputStream。打印:

Connected.
reading...

并且一直阻塞在in.read(); 上。接下来我设置so timeout,代码如下:

long t1 = 0; 
try { 
socket = new Socket(); 
socket.connect(new InetSocketAddress("localhost", 8080)); 
// 设置so timeout 为2000毫秒 
socket.setSoTimeout(2000); 
System.out.println("Connected."); 
in = socket.getInputStream(); 
System.out.println("reading..."); 
t1 = System.currentTimeMillis(); 
in.read(); 
} catch (IOException e) { 
long t2 = System.currentTimeMillis(); 
System.out.println("read end, take -> " + (t2 - t1) + "ms"); 
e.printStackTrace(); 
} finally { 
if (this.reader != null) { 
try { 
this.reader.close(); 
} catch (IOException e) { 
} 
} 
}

抛出异常:java.net.SocketTimeoutException: Read timed out, 打印:read end, take -> 2000ms , 说明so timeout起作用了。

1.3 小结

我们可以通过设置connect timeout来控制连接建立的超时时间(不是绝对的,当设置的主机名不合法,比如我设置主机名为abc,会抛异常java.net.UnknownHostException: abc,但是此时connect timeout设置是不起作用的,测试得出的结论,仅供参考)。

通过设置so timeout可以控制流读取数据的超时时间。

2. 使用案例

2.1 mysql jdbc timeout

查阅Mysql Connector/J 5.1 Developer Guide 中的jdbc配置参数,有

connectTimeout

Timeout for socket connect (in milliseconds), with 0 being no timeout. Only works on JDK-1.4 or newer. Defaults to '0'.

Default: 0

Since version: 3.0.1

socketTimeout

Timeout on network socket operations (0, the default means no timeout).

Default: 0

Since version: 3.0.1

这两个参数分别就是对应上面我们分析的connect timeout和so timeout。

参数的设置方法有两种,一种是通过url设置,

jdbc:mysql://[host1][:port1][,[host2][:port2]]...[/[database]] [?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]

即在url后面通过?加参数,比如

jdbc:mysql://192.168.1.1:3306/test?connectTimeout=2000&socketTime=2000

还有一种方式是:

Properties info = new Properties(); 
info.put("user", this.username); 
info.put("passWord", this.password); 
info.put("connectTimeout", "2000"); 
info.put("socketTime", "2000"); 
return DriverManager.getConnection(this.url, info); 

2.2 Jedis timeout

Jedis是最流行的redis java客户端工具,redis.clients.jedis.Jedis对象的构造器中就有参数设置,

public Jedis(final String host, final int port, final int connectionTimeout, final int soTimeout) { 
super(host, port, connectionTimeout, soTimeout); 
} 
// 用一个参数timeout同时设置connect timeout 和 so timeout 
public Jedis(final String host, final int port, final int timeout) { 
super(host, port, timeout); 
}

Jedis中so timeout个人觉得是有比较重要意义的,首先jedis so timeout默认值为2000毫秒,jedis的操作流程是客户端发送命令给服务器端执行,然后客户端就开始执行InputStream.read()读取响应,当某个命令比较耗时(比如数据非常多的情况下执行“keys *”),而导致客户端迟迟没有收到响应,就可能导致java.net.SocketTimeoutException: Read timed out异常抛出。

一般是不建议客户端执行非常耗时的命令,但是也不排除有这种特殊逻辑,那这时候就有可能需要修改Jeids中这个so timeout的值。

3. 总结

了解了这两个timeout之后,可以更好的处理一些网络服务的客户端和服务端,同时对排查一些问题也很有帮助。

一般的成熟的网络服务和客户端都应该有这两个参数的配置方法,当使用遇到类似问题可以从这个方向去考虑下。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: JavaSocket设置timeout的几种常用方式说明

本文链接: https://lsjlt.com/news/171113.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaSocket设置timeout的几种常用方式说明
    目录1. Socket timeout1.1 建立连接connect timeout1.2 读取数据so timeout1.3 小结2. 使用案例2.1 MySQL jdbc tim...
    99+
    2022-11-13
    Java Socket Socket设置timeout Java Socket设置timeout
  • 说说Java异步调用的几种方式
    目录一、通过创建新线程二、通过线程池三、通过@Async注解四、通过CompletableFuture日常开发中,会经常遇到说,前台调服务,然后触发一个比较耗时的异步服务,且不用等异...
    99+
    2024-04-02
  • recover三种方式的说明
    1 SQL>recover database; 该命令用来对所有数据文件进行恢复,只能使用保存在文件系统上的归档日志及在线日志。使用此类命令的前提是控制文件不可以是还原或重建得来的。 SQL>r...
    99+
    2024-04-02
  • 达梦数据库的几种模式及状态说明
    一、达梦数据库三种模式 达梦数据库支持 3 种数据库模式: Normal 模式、 Primary 模式和 Standby 模式。 1.1 Normal 模式 用户可以正常访问数据库,操作没有限制。 正常生成本地归档,但不发送实时归档...
    99+
    2023-09-09
    数据库 sql 服务器 DM 达梦数据库 Powered by 金山文档
  • Redis常用的配置和说明
    #是否作为守护进程运行,默认为nodaemonize yes#配置pid的存放路径及文件名,默认为当前路径下,此设置当守护进程运行时有效pidfile redis.pid#Redis默认监听端口port 6...
    99+
    2024-04-02
  • js函数声明的方式有几种
    这篇文章主要介绍“js函数声明的方式有几种”,在日常操作中,相信很多人在js函数声明的方式有几种问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”js函数声明的方式有几种”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-20
  • 用python 访问redis的几种常用方式
    1,配置sentinel from redis.sentinel import Sentinel sentinel = Sentinel([('192.168.0.210', 26379),('192.16...
    99+
    2024-04-02
  • DedeCMS FTP设置的作用说明
    问:Dedecms V5.3后台FTP设置是用来干什么的?是不是没用啊?怎么用啊? 答:如果你用的是linux系统,你会发现,如果你权限不足,就不能生成栏目什么的,这时,系统就会用的设好的FTP信息登陆,用他来创建一些东...
    99+
    2022-06-12
    DedeCMS FTP设置
  • python的几种常用安装包的方式
    使用自带的pip 打开windows命令行,不需要输入“python”或输入”python3”,而是直接输入以下指令。我们默认系统环境变量已经按照安装位置设置好。 一般安装之后默认是已经安装好了pip,我们可以直接使用: 对于...
    99+
    2023-01-31
    几种 安装包 常用
  • idea设置JVM运行参数的几种方式
    目录方式一方式二方式三对JVM运行参数进行修改是JVM性能调优的重要手段,下面介绍在应用程序开发过程中JVM参数设置的几种方式。 方式一 java程序运行时指定 -Dproperty...
    99+
    2024-04-02
  • vue-cli中设置publicPath的几种方式对比
    目录设置publicPath的几种方式对比publicPath打包设置vue.config.js publicPath "./" npm run build无效设...
    99+
    2024-04-02
  • 常用的android加密方式有哪几种
    常用的Android加密方式有以下几种:1. 文件加密:通过对文件进行加密,确保文件内容的机密性,常见的文件加密算法有AES(Adv...
    99+
    2023-10-18
    android
  • golang 切片的三种使用方式及区别的说明
    概念 切片(slice)是建立在数组之上的更方便,更灵活,更强大的数据结构。切片并不存储任何元素而只是对现有数组的引用。 三种方式及细节案例 ①定义一个切片,然后让切片去引用一个已经...
    99+
    2024-04-02
  • 云服务器有哪几种方式设置
    云服务器可以提供多种不同的操作方式来设置和管理云服务器。以下是一些常见的云服务器设置方式,您可以根据实际情况进行选择和设置: 自定义参数设置:您可以为云服务器添加自定义参数,以控制云服务器的各种功能和性能。您可以选择将数据存储在本地数据...
    99+
    2023-10-26
    几种 方式 服务器
  • Keycloak各种配置及API的使用说明
    目录1.创建client2.怎样拿到access token信息 2.1采用前端登录(例如angular应用)的情况2.2 使用keycloak API3.拿到用户role...
    99+
    2023-03-09
    Keycloak配置 API的使用 Keycloak各种配置
  • MySQL表关联的常用方式有哪几种
    本文主要给大家介绍MySQL表关联的常用方式有哪几种,文章内容都是笔者用心摘选和编辑的,具有一定的针对性,对大家的参考意义还是比较大的,下面跟笔者一起了解下MySQL表关联的常用方式有哪几种吧。建表及插入数...
    99+
    2024-04-02
  • golang post请求常用的几种方式小结
    post请求常用的几种方式,记录一下 func httpPost() { resp, err := http.Post("https://www.abcd123.top/...
    99+
    2024-04-02
  • mysql复制表的几种常用方式总结
    目录mysql复制表的几种方式 1、复制表结构及数据到新表2、只复制表结构到新表3、复制旧表的数据到新表(假设两个表结构一样)4、复制旧表的数据到新表(假设两个表结构不一样)5、可以将表1结构复制到表26、可以...
    99+
    2023-04-10
    mysql复制表语句 mysql如何复制表 mysql数据表复制
  • golang中常用的几种编码解码方式
    当我们需要将一个编码格式转换成另一个编码格式时,就需要用到转码。在Go语言中,转码操作非常方便,可以使用内置的encoding包来快速完成转码操作。Go语言中的encoding包提供了许多常用的编码解码方式,例如JSON、XML、Base6...
    99+
    2023-05-14
  • adb连接设备的几种方式
    1、USB连接 前提条件: 一台已安装adb环境的电脑一台手机、一根可传输数据的线(数据线,非充电线) 连接步骤: 将手机上的开发者选项打开(一般是:设置 > 关于手机,然后点按版本号七次)进入开发者...
    99+
    2023-09-01
    android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作