2334

Tcp“长连接”实战中的总结

乐果   发表于   2017 年 11 月 02 日 标签:tcp

因开发公司“灯控中转服务”(穿透客户端网络限制)过程中,用了tcp长连接,持续的踩坑,慢慢的对这种 网络多变网络不稳定 环境下的Tcp服务通信,有了更加清晰的认识,现总结一下。

一、理解:tcp是面向链接的,http是无状态的

tcp是建立在ip链接上,没有链接就没有通信。

http当然也是建立在tcp的基础上,但因为常用的是短链接,即链即用,所谓无状态是指“身份标识”,tcp也无身份标志,这都要靠协议自身的约定来保证,比如http为了身份状态识别,client端有cookie,server端有session,client在每次请求的报文中,都带上了cookie让server端能识别。

二、tcp在静默状态下,对链路状态无感知

tcp是面向链接的,但是,链接依赖的链路断了(也就是ip层),tcp两端其实并不会知道,只有当他们之间有报文往来的时候,才会发现报文无法到达对方(所依赖的网络链路已经发生变化)

实验:

对链接上服务的两端,中途快速把网线拔掉,然后迅速插上,此时双方ip未发送变化,服务两端的链接依然能通信~

三、服务端自我保护机制—超时, 短链接与长链接的区别

短链接:比如http请求,mysql短链接,一般server为了保护服务端不至于因长时间的占用(浪费),导致可用的链接资源被耗尽,因此server在建立链接后会设置超时来保护。即超过设定的时间,链接即自动被断开释放。

长链接:即区别与短链接,根据实际情况设置不同的规则。当然,都需要有保护机制~

四、长链接如何保证,以“灯控服务”为例,需要解决的坑

1、close未有效送出,对方无感知:

a、client退出close未有效送达,server不知道,链接池map未更新。。。。

问题/解决:

1> 会出现管理后台发送的“指令”下发失败,因为链接池map中的链接(对方)实际上已经断开;

2> 会出现重复链接:之前在做灯控中转服务的时候,并未考虑重复链接的问题,因此采用了如有相同标识的链接请求,如发现链接池map中存在,会直接拒绝; 之后修改了策略,重复链接,新的链接会取代map中的旧链接,但在这个过程中,又因为旧链接资源并未有效释放,后来导致系统分配的资源耗尽而无法接收新的链接请求。。。

b、server主动close未有效送达,client不知道,它会傻等。。。。

问题/解决:

1> 链接处于断开状态,只能等待client再次发出链接请求,在这一段时间,处于无法控制的状态;

那么,对方如何有效感知?心跳机制、超时机制。。。
2、网络断开/ip地址发生改变

a、server/client在不发送通信前,都不知道,只有向对方发送指令(报文)时,才会报错。。。

问题/解决:

1> 不会事先知道,待用户发指令时会报错;

2> 如果事先知道,第一时间重新链接,以链接可用的状态等待用户的指令;

那么,如何事先知道?心跳机制。。。
3、心跳报文 与 用户指令报文 有序传达

1> 心跳由服务端定期发出:周期时长?

2> 心跳、用户指令 都属于报文,tcp的请求/应答是阻塞的,一般情况即一应一答,因此要保证每次请求有序进行:原子锁/阻塞,保证有效进行一应一答。

3> 客户端没有心跳机制,如何保护?超时重链:没有报文活跃的连续时间超过多少,就认为是网络断开了,重新发起链接请求。超时时长?

4> 上述1、3中,server端的心跳周期时长值 应小于 client超时时长值。

五、常用调试工具

tcpdump采用命令行方式,它的命令格式为:

tcpdump [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ]
        [ -i 网络接口 ] [ -r 文件名] [ -s snaplen ]
        [ -T 类型 ] [ -w 文件名 ] [表达式 ]

tcpdump的选项介绍
   -a    将网络地址和广播地址转变成名字;
   -d    将匹配信息包的代码以人们能够理解的汇编格式给出;
   -dd    将匹配信息包的代码以c语言程序段的格式给出;
   -ddd    将匹配信息包的代码以十进制的形式给出;
   -e    在输出行打印出数据链路层的头部信息;
   -f    将外部的Internet地址以数字的形式打印出来;
   -l    使标准输出变为缓冲行形式;
   -n    不把网络地址转换成名字;
   -t    在输出的每一行不打印时间戳;
   -v    输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息;
   -vv    输出详细的报文信息;
   -c    在收到指定的包的数目后,tcpdump就会停止;
   -F    从指定的文件中读取表达式,忽略其它的表达式;
   -i    指定监听的网络接口;
   -r    从指定的文件中读取包(这些包一般通过-w选项产生);
   -w    直接将包写入文件中,并不分析和打印出来;
   -T    将监听到的包直接解释为指定的类型的报文,常见的类型有rpc(远程过程
调用)和snmp(简单网络管理协议;)

例如,在对接奥普闸机tcp协议时:

tcpdump -i en0 port 3691 -X -w aopu.cap

乐果   发表于   2017 年 11 月 02 日 标签:tcp

0

文章评论