基于TCP的心跳和加密设计
second60 20180212
1 前言
本章主要讲解的心跳是逻辑上的心跳,非TCP内部的心跳。一般TCP服务器都会在逻辑层做一个心跳,主要用来客户端无心跳请求时,确定客户端是否存活。对于手机客户端或弱网环境,是非常有必要的。
适用于:客户端与服务端,和服务与服务之间底层实现。
-----------------------------------------------------------------------------------------------------
2. 解释
心跳:客户端请求发起请求,然后服务端收到并回复时间戳。
(注:心跳可以由客户端发起,也可以由服务端发起,只是主动方和被动方不同,看需求,正常是由客户端发起。)
心跳包是用来维持和让服务器清楚客户端连接是否存活的工具之一。
加密:客户端和服务端通讯时采用的非明文的方式,防止数据很容易被分析或**。主要是为了安全。
-----------------------------------------------------------------------------------------------------
2.1 心跳
本例以客户端发起请求为例。
单次心跳时间:60s
1. 客户端发送心跳,内容为一个时间戳即可。
2. 服务端收到后,回复一个服务器的时间戳。
3. 如果客户端没收到回复,会重试发送心跳,数次没有收到后,close(fd)并做断网处理。
4. 如果服务端在两次(120s)设置的单次心跳时间,没收到,close(fd)并做断网处理。
正常情况下,客户端或主动关闭TCP,对方都会收到read=0,所以是清楚知道对方是否存活。
但对于异常情况,网络波动或异常,手机客户端切换到后台,在地铁弱网波动,经常连接是没有断开的,但是信息是发不出去的。所以心跳的目的就是为了网络在异常情况下,判断连接是否还存活,如果超过最大存活时间,当然不存活处理,主动断开连接,所以异常后再连回来,还是当正常处理。防止大量异常不存活的连接大量存在。
-----------------------------------------------------------------------------------------------------
2.2 加密
我这里并不讲加密的具体内容,只讲下加密常用的一种方式。
正常来说,比较安全的加密方式,加密种子并不在客户端,而是由服务端生成加密种子后,发送给客户端,然后客户端所发送的所有协议内容都是通过加密后的内容。
-----------------------------------------------------------------------------------------------------
3 心跳和加密使用
上面讲解完心跳和加密的方法,那么下面就介绍下整体设计吧。
在此举的例子为:客户端和网关之间。(所有的服务与服务间都可使用)
在分布式设计中,客户端正常都是连接到网关服务,网关服务,是客户端交互的唯一入口。(当然其他的可以通过http交互,这里假设没有)
服务端内部服务都是与网关交互,通过RPC等进行交互。
网关主要的功能:
1. 接收并转发客户端的消息
2. 连接和断线主动处理
3. 心跳和加密处理
4. 把消息发送给客户端
网关的心跳和加密流程:
1. 客户端发起连接
2. 服务端连接成功,返回加密种子
3. 客户端拿加密种子发送消息,其中第一个消息为心跳
4. 服务端回复心跳
(到此为止,正常连接)
5. 客户端服务端正常交互
但,怎么来验证连接是否正常的连接呢?方法如下:
1. 数据读取异常(小于最小值,大于最大值)
2. 发送来的消息,格式不对。read error, pack error
例,格式:len(16位)+cmd(16位)+加密(打包内容)
len(16位)+加密(cmd(16位)+打包内容)
3. 发送来的消息,解不了密,异常
(上面都是底层打包解包的错误)
4. 发送的消息错(如未登陆,发送其他消息,业务上的错)
5. 非法调用等
上面1- 3步骤,正常情况下都不会发生,所以异常这种情况的一般做法就是关闭连接。让客户端重新连接。防止非法的连接。
对于业务上的错,就要看业务来处理。没登陆成功,发送了需登陆后才能的操作,是非法的。可以让客户端首先登陆成功后,才能操作。防止非法调用。
正常情况,登陆协议都是心跳后的第一个协议。登陆成功,网关会有些用户的状态信息,当连接断开后,状态信息会清除。
整体消息流程图: