网络知识--基础知识点--tcp长短连接、http长短连接、心跳包、tcp KeepAlive保活机制

1. 通信方式

全双工:允许数据同时(瞬时)在两个方向上传输。双方在同一时刻既可以发送也可以接收数据。比如:电话。
半双工:允许数据在两个方向上传输。但是,在某一时刻,只允许数据在一个方向上传输。比如:对讲机。
单工:只允许数据在一个方向上传输。一个是发送方,另一个是接收方,双方的角色不能互换,不能实现双向通信。比如:广播。

tcp属于全双工通信。

2.在理想状况下

对于一条处于Established状态的tcp连接,在理想状况下,即使中间路由器可以崩溃和重启,数据线可以断开在连接,只要连接两端的主机没有被重新启动(或更改IP地址),那么该tcp连接永远不会断。

理想状况:

  • 客户端和服务器都没有实现应用层的非活动状态检测计时器,该计时器超时会导致任何一个应用进程终止。(即:程序员不做任何的应用层心跳处理及对tcp中KEEP_LIVE的心跳设置的情况下)
  • 中间路由器不能保存连接的相关状态,例如一个NAT配置信息。
  • 某些特定从左常常需要这些状态,而它们也会由于非活动状态而删除,或者由于系统故障而丢失。

可这种理想状况在现在的网络环境中时很难实现的。

3. tcp长短连接、http长短连接
3.1 概念

长连接和短连接的概念在TCP协议中并没有直接的定义,而是在应用层协议(比如HTTP)中通过控制TCP连接的打开和关闭来实现的。

http短连接

  • 一个tcp连接建立好后只进行一次http的“请求-响应过程”,之后就会断开。http1.0默认,可通过设置Connection:keep-alive变成长连接。

http长连接

  • 一个tcp连接建立好后可进行多次http的“请求-响应过程”,之后就会断开。http1.1默认,可通过设置Connection:close变成短连接。

tcp长短连接通过使用应用层心跳包或tcp自带的KeepAlive保活机制以及close函数的运行时机来控制。

3.2 使用场景

长连接多用于操作频繁(读写),点对点的通讯,而且并发相对不高的情况。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,每次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。QQ、微信通信软件。

短连接多用于高并发的情况。WEB网站的http服务一般都用短链接(http1.0只支持短连接,1.1keep alive 带时间,操作次数限制的长连接),因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好;

3.3 优缺点

在这里插入图片描述

4. 心跳包
4.1 概念

心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送,类似于心跳,所以叫做心跳包。

4.2 两种典型的即时通讯网络层问题情型

1)情形一:一个客户端连接服务器以后,如果长期没有和服务器有数据来往,可能会被防火墙程序关闭连接,有时候我们并不想要被关闭连接。例如,对于一个即时通讯软件来说,如果服务器没有消息时,我们确实不会和服务器有任何数据交换,但是如果连接被关闭了,有新消息来时,我们再也没法收到了,这就违背了“即时通讯”的设计要求。

2)情形二:通常情况下,服务器与某个客户端一般不是位于同一个网络,其之间可能经过数个路由器和交换机,如果其中某个必经路由器或者交换器出现了故障,并且一段时间内没有恢复,导致这之间的链路不再畅通,而此时服务器与客户端之间也没有数据进行交换,由于 TCP 连接是状态机,对于这种情况,无论是客户端或者服务器都无法感知与对方的连接是否正常,这类连接我们一般称之为“死链”。

4.3 对于即时通讯通常的解决思路:

1)针对情形一:此应用场景要求必须保持客户端与服务器之间的连接正常,就是我们通常所说的“保活“。如上所述,当服务器与客户端一定时间内没有有效业务数据来往时,我们只需要给对端发送心跳包即可实现保活。

2)针对情形二:要解决死链问题,只要我们此时任意一端给对端发送一个数据包即可检测链路是否正常,这类数据包我们也称之为”心跳包”,这种操作我们称之为“心跳检测”。顾名思义,如果一个人没有心跳了,可能已经死亡了;一个连接长时间没有正常数据来往,也没有心跳包来往,就可以认为这个连接已经不存在,为了节约服务器连接资源,我们可以通过关闭 socket,回收连接资源。

4.4 双向心跳

心跳包需要双向心跳,因为心跳包的发送是发送方为了检测接收方是否断线而发送的。而双方都可能由于不可原因断线,因此需要双向心跳。

4.5 心跳包的意义
  • 进行发送方对接收方的断线检测。
  • 保活。
5. tcp的KeepAlive机制
5.1 tcp的KeepAlive机制详解

初步了解可跳过该部分直接看6.2总结部分

5.1.1

默认的KeepaliveKeepalive(存活定时器)超时需要7,200,000 milliseconds,即2小时,探测次数为5次。它的功效和用户自己实现的心跳机制是一样的。开启Keepalive功能需要消耗额外的宽带和流量,尽管这微不足道,但在按流量计费的环境下增加了费用,另一方面,Keepalive设置不合理时可能会因为短暂的网络波动而断开健康的TCP连接。

keepalive并不是TCP规范的一部分。在Host Requirements RFC罗列有不使用它的三个理由:(1)在短暂的故障期间,它们可能引起一个良好连接(good connection)被释放(dropped),(2)它们消费了不必要的宽带,(3)在以数据包计费的互联网上它们(额外)花费金钱。然而,在许多的实现中提供了存活定时器。

一些服务器应用程序可能代表客户端占用资源,它们需要知道客户端主机是否崩溃。存活定时器可以为这些应用程序提供探测服务。Telnet服务器和Rlogin服务器的许多版本都默认提供存活选项。
个人计算机用户使用TCP/IP协议通过Telnet登录一台主机,这是能够说明需要使用存活定时器的一个常用例子。如果某个用户在使用结束时只是关掉了电源,而没有注销(log off),那么他就留下了一个半打开(half-open)的连接。如果客户端消失,留给了服务器端半打开的连接,并且服务器又在等待客户端的数据,那么等待将永远持续下去。存活特征的目的就是在服务器端检测这种半打开连接。
也可以在客户端设置存活器选项,且没有不允许这样做的理由,但通常设置在服务器。如果连接两端都需要探测对方是否消失,那么就可以在两端同时设置(比如NFS)。

5.1.2 keepalive工作原理

若在一个给定连接上,两小时之内无任何活动,服务器便向客户端发送一个探测段。(我们将在下面的例子中看到探测段的样子。)客户端主机必须是下列四种状态之一:

  1. 客户端主机依旧活跃(up)运行,并且从服务器可到达。从客户端TCP的正常响应,服务器知道对方仍然活跃。服务器的TCP为接下来的两小时复位存活定时器,如果在这两个小时到期之前,连接上发生应用程序的通信,则定时器重新为往下的两小时复位,并且接着交换数据。
  2. 客户端已经崩溃,或者已经关闭(down),或者正在重启过程中。在这两种情况下,它的TCP都不会响应。服务器没有收到对其发出探测的响应,并且在75秒之后超时。服务器将总共发送10个这样的探测,每个探测75秒。如果没有收到一个响应,它就认为客户端主机已经关闭并终止连接。
  3. 客户端曾经崩溃,但已经重启。这种情况下,服务器将会收到对其存活探测的响应,但该响应是一个复位,从而引起服务器对连接的终止。
  4. 客户端主机活跃运行,但从服务器不可到达。这与状态2类似,因为TCP无法区别它们两个。它所能表明的仅是未收到对其探测的回复。

服务器不必担心客户端主机被关闭然后重启的情况(这里指的是操作员执行的正常关闭,而不是主机的崩溃)。当系统被操作员关闭时,所有的应用程序进程(也就是客户端进程)都将被终止,客户端TCP会在连接上发送一个FIN。收到这个FIN后,服务器TCP向服务器进程报告一个文件结束,以允许服务器检测这种状态。

在第一种状态下,服务器应用程序不知道存活探测是否发生。凡事都是由TCP层处理的,存活探测对应用程序透明,直到后面2,3,4三种状态发生。在这三种状态下,通过服务器的TCP,返回给服务器应用程序错误信息。(通常服务器向网络发出一个读请求,等待客户端的数据。如果存活特征返回一个错误信息,则将该信息作为读操作的返回值返回给服务器。)在状态2,错误信息类似于“连接超时”。状态3则为“连接被对方复位”。第四种状态看起来像连接超时,或者根据是否收到与该连接相关的ICMP错误信息,而可能返回其它的错误信息。

5.2 tcp的KeepAlive机制总结

tcp的KeepAlive机制与心跳包的原理相同。默认两小时之内双方之间没有任何数据包发送,则在两小时到达时开启KeepAlive的一方会发送探
测包(心跳包)。75秒内若有相应的ack确认包返回,则会修改连接开始时间继续保持连接;若没有相应的ack确认包返回,发送方会总共发送10个这样的探测,每
个探测75秒。如果没有收到一个响应,发送方就认为对方主机已经关闭并终止连接。

tcp的KeepAlive机制中发送探测报文之前的连接空闲时间(tcp_keepalive_time)、两次探测报文发送的时间间隔(tcp_keepalive_intvl)和探测的次数(tcp_keepalive_probes)可以通过程序员进行设置。但是一般不会修改,它的修改是内核级的,导致该机器上的所有应用KeepAlive的这三个量都会发生改变。

6.应用层心跳包 VS tcp的KeepAlive保活机制

应用层的心跳数据包会耗费更多的带宽,因为TCP协议的保活机制发送的是数据长度为零心跳包,而应用层的心跳数据包长度则必然会大于0。

应用层的心跳数据包可以带一些应用所需要的数据,随应用自己控制,而TCP协议的保活机制则是对于应用层透明的,无法利用心跳携带数据。

注:应用层心跳包在应用层是不需要对方发送数据进行响应的,发送方内核在传输层会将程序员在应用层所要发送的探测数据打包(此处称为心跳包)给对方发送,等待对方内核回复一个ACK确认包。不会有应用层的响应。

7. http1.1中keep-alive VS tcp的KeepAlive

http1.1中keep-alive VS tcp的KeepAlive两者之间没有任何联系。

http1.1中keep-alive是Connection值,表示在应用层可以使用同一个tcp连接进行多次请求--响应这一过程。根据Connection的值客户端和服务端决定是否通过close()断掉tcp连接。

补充:

  • maxConnect用于控制一个tcp连接可以最多进行几次请求--响应这一过程。达到最大次数后,会通过close()断掉tcp连接。
  • KeepAliveTimeout控制一个tcp连接最长保存时间,时间到后会通过close()断掉tcp连接。
  • Connection浏览器和服务器都可以设置,maxConnect与KeepAlive Tivemout一般在浏览器设置(该条可能有误,需注意)。

tcp的KeepAlive是用于断线检测和tcp保活。默认两小时之内双方之间没有任何数据包发送,则在两小到达时开启KeepAlive的一方会发送探测包(心跳包)。75秒内若有相应的ack确认包返回,则会修改连接开始时间继续保持连接;若没有相应的ack确认包返回,发送方会总共发送10个这样的探测,每个探测75秒。如果没有收到一个响应,发送方就认为对方主机已经关闭并终止连接。

8.http中的“请求-响应”VS tcp的包的发送与回复

“请求-响应”属于应用层面,tcp的包的发送与回复属于传输层,仅仅是应用层对传输层的使用。

当客户端应用层需要发送请求时,客户端内核会将请求打包(可能分成多个包)发送给服务端。服务端内核会给每个已接收的包回复一个ACK包,然后服务端应用层会得到请求,在应用层完成业务逻辑处理后会将结果作为响应发送给客户端。服务端内核将响应信息打包(可能分成多个包)发送给客户端,客户端内核会给每个已接收的包回复一个ACK包,然后客户端应用层会得到服务端响应的信息。




[参考博客]
网络连接中的长连接和短链接是什么意思?
如何选择TCP长连接与短连接
python socket 编程之三:长连接、短连接以及心跳
一文读懂即时通讯应用中的网络心跳包机制:作用、原理、实现思路等
为什么心跳包(HeartBeat)是必须的?
TCP长连接和保活时间

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值