java判断连接超时_网络基础知识--连接

1、问题

  1. 对方连接断掉了我知道吗?
  2. 连接超时设置多少合适?依据是什么?可以有一个统一值吗?
  3. 如何建立一个连接?
  4. 什么是长连接什么是短连接?
  5. 如何使用一个连接?

2、TCP连接

什么是一个TCP连接?机器A通过一个IP和端口与机器B的一个IP和端口通过TCP的三次握手建立的逻辑联系,用于可靠数据传输。

特点

  1. 占用一个端口;
  2. 可以用netstat -ntlp 进行查看(windows下 “netstat -qn -p TCP”);
  3. 有心跳,linux下默认的心跳间隔时间为2小时。

3、如何建立一个连接

Java代码:

Socket socket = new Socket();
SocketAddress remoteAddr = new InetSocketAddress("61.144.222.17" ,22);
socket.connect(remoteAddr);

4、如何使用一个连接

建立连接之后有什么用?一般情况都是获取数据。一般情况获取数据都是发送一个请求,对方(一般是提供服务者,即服务器)回一个响应,响应里包含了要获取的数据。

4.1 写
即发送请求。Java代码:

OutputStream os = socket.getOutputStream();
byte b[] = {'a' , 'b' , 'c'};
os.write(b);

4.2 读
即获取服务器的响应。注意:读的前提是服务器要把数据写入了连接,客户端才有数据可读,这时读才会返回,否则读会一直等待。

Java代码:

InputStream is = socket.getInputStream();
is.read(b);

有没有不是一个请求一个响应的连接?心跳、tcp连接的直播、老式论坛等。

4.3 高级篇(常见的url请求、执行sql语句、获取redis数据是如何使用链接的)

d4d49ba57a0cf09550efe1fddd6bfc6a.png

上图是Http客户端的一种设计,目的是想说明我们日常用得最多的http协议类,与连接的关系。

说明:

  1. Java已经有socket类了,PHP和c需要自己用内置socket函数实现Socket类。
  2. 连接类就是包含了socket实例,拥有连接、断连、读写功能的类。符合上面对连接作用的描述。
  3. 而HttpClient就是一个连接,只不过实现了Http协议。其实外部使用者可以直接传入一个HttpRequest对象给execute方法,execute方法会调用HttpRequest的serialize方法把http协议的header、body序列化成字符串,通过Connection的write发送给服务器。然后调用Connection的read方法,读取到服务器的响应字符串,再调用HttpResponse的Unserialize静态方法把字符串反序列化为HttpResponse对象。
  4. 而我们常见的CURL,又是对HttpClient的封装,简化了我们调用的代码。

5、超时时间

5.1 连接超时时间

为什么会有连接超时?因为TCP协议三次握手的第一次由客户端发送syn数据包,就开始等待服务器的响应,这时如果服务器主机不存在,就没有人回复ack,这是tcp协议定义的通信机制。这时,只有客户端自己根据时间判断是否这个syn包真的丢失了,或者说你(业务)能容忍的超时时间。

超时时间的设置,一般为客户端与服务器之间的网络延迟时间(一个来回),再适当放大几毫秒。网络延迟可以通过ping获得,因为ping是一个来回,TCP协议连接时的三次握手也是一个来回的时间(客户端回完ack包之后,就标志连接已经建立,所以其实只有一个来回的数据传输)。

比如在windows上北京ping深圳的主机,获得“往返行程的估计时间(以毫秒为单位):最短 = 37ms,最长 = 37ms,平均 = 37ms”,比较稳定,那连接超时可以设置为42ms;

5.2 写超时时间

Java里没有写超时时间。

5.4 读超时时间

5.4.1 为什么会有读超时时间?

  1. 网络传输有延时;
  2. 上面说的读的前提是服务器把数据写入连接,如果服务器写数据花了很长时间,或者很长时间之后再写,甚至服务器程序出错,都可能导致连接无数据可读,最终导致读超时;
  3. 网络抖动导致连接丢失。这是最常见也是最严重的情况,如果这种情况的连接丢失,客户端是感知不到的(直接拔网线,客户端也无法感知),所以客户端会一直在读等待,直到超时。如果没有设置读超时,也没有更改默认的tcp心跳时间,那这次读操作将在2小时(linux默认的tcp心跳是2小时)后才会返回错误(类似SocketErrorException)。
  4. 读超时时间的上层表现可能是请求超时时间(上例设计中的HttpClient),数据库的SQL语句执行时间等;

5.4.2 读超时设置多少合适?

根据业务制定。比如app 5s就弹出超时提示,不再等待服务器响应了,那么nginx的requestTimeout就设置为5s;如果是对redis的读,因为redis本身很快,就可以设置100ms(不能存储大对象);

5.4.3 为什么要设置超时时间?

如果不设置连接超时时间,当主机ip不存在(未开机,ping不通)或网络包丢失,就会导致花在连接上的时间会很长,无法快速进行重试(切换到下一个可用机器上),也无法快速失败。这样会导致占用大量连接或线程资源。

如果不设置读超时时间,会导致占用连接资源,占用线程资源。最常见的危害是占用线程资源,比如处理任务的最大线程数是20,如果每个任务都有访问其他网络资源,当网络发生抖动导致连接丢失,如果这时20个线程刚发生读请求,就会一直处于等待状态,线程无法结束,就无法接收新任务,导致服务夯死,最中还导致Listen Drop。

5.4.4 系统默认超时时间是多少?

  1. 连接超时时间linux系统为60s;
  2. 系统没有读超时时间默认值。但在网络断链无感知的情况下,取决于tcp心跳,默认是2小时。

作者:

轻易科技研发中心-金融研发中心-游克江

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值