介绍
本项目在TCP/IP协议之上构建了一套支持重连和加密的流式网络通讯协议。
此协议的实现目的主要是提升长连接型应用在移动终端上的连接稳定性。
以期在可能的情况下尽量保证用户体验的连贯性,同时又不需要对已有代码做大量的修改。
协议
基本流程:
- 客户端连接服务端时,协议采用DH密钥交换算法和服务端之间协商出一个通讯密钥
- 在后续的通讯过程中,双方使用这个密钥对通讯内容进行RC4流式加密
- 通讯双方,均在本地缓存一定量的历史数据,并记录已接收和已发送的字节数
- 当底层TCP/IP连接意外断开时,客户端将新建一个连接并尝试重连,服务端将等待重连
- 当新的连接创建成功,客户端和服务端之间互发已接收和已发送的字节数
- 客户端和服务端各自比对双方的收发字节数来重传数据
- 重连过程中,服务端使用之前协商的通讯密钥验证客户端的身份合法性
新建连接,上行:
-
新建连接时,客户端先发送一个全0的字节告知服务端这是一个新连接
-
接着客户端发送8个字节的握手请求,PublicKey为DH密钥交换用的公钥
+------------+ | Public Key | +------------+ 8 byte
-
客户端收到挑战码后,发送16个字节的验证请求
-
MD5为收到的挑战码加通讯密钥计算得出的MD5哈希值
+------------+ | MD5 | +------------+ 16 byte
新建连接,下行:
-
当服务端收到新建连接请求后,下发24个字节的握手响应
-
消息前8个字节为DH密钥交换用的公钥
-
消息第[8, 16]字节为加密后的连接ID,加密所需密钥通过DH密钥交换算法计算得出
-
消息第[16, 24]字节为挑战码,一个uint64范围内的随机数
+------------+-----------------+------------------+ | Public Key | Crypted Conn ID | Challenge Code | +------------+-----------------+------------------+ 8 byte 8 byte 8 byte
-
当服务器收到验证码MD5后,验证合法性;若非法连接则立即断开
重连,上行:
-
当客户端尝试重连时,新建一个TCP/IP连接,并发送一个全1的字节告知服务端这是一个重连
-
接着客服端发送40个字节的重连请求
-
消息前8个字节为连接ID
-
消息的[8, 16)字节为客户端已发送字节数
-
消息第[16, 24)字节为客户端已接收字节数
-
消息第[24, 40)字节为消息前24个字节加通讯密钥计算得出的MD5哈希值
+---------+-------------+------------+---------+ | Conn ID | Write Count | Read Count | MD5 | +---------+-------------+------------+---------+ 8 byte 8 byte 8 byte 16 byte
-
客户端收到挑战码后,发送16个字节的验证请求
-
MD5为收到的挑战码加通讯密钥计算得出的MD5哈希值
+------------+ | MD5 | +------------+ 16 byte
重连,下行:
-
当服务端接收到重连请求时,对连接的合法性进行验证
-
服务端下发24个字节的重连响应
-
消息前8个字节为服务端已发送字节数
-
消息第[8, 16]字节为服务端已接收字节数
-
消息第[16, 24]字节为重连挑战码
-
验证失败则已发送字节数、已接收字节数、重连挑战码始终为0
-
验证成功则下发服务端已发送字节数、已接收字节数、重连挑战码
-
客户端在收到重连响应后,先发送验证码,然后比较收发字节数差值来读取服务端下发的重传数据
+-------------+------------+------------------+ | Write Count | Read Count | Challenge Code | +-------------+------------+------------------+ 8 byte 8 byte 8 byte
-
当服务器收到重连验证码MD5后,验证合法性;若非法连接则立即断开
-
紧接着服务端立即下发需要重传的数据
实现
本协议目前有以下编程语言的实现:
资料
TODO
- 自定义加密算法
- 重连失败的响应
参与
欢迎提交通过github的issues功能提交反馈或提问。
技术群:474995422