常用tcp协议交互的分析解读及与socket编程之间的关系

在日常工作中,接触最多的就是tcp协议了,大家可能对于最基础的tcp交互都略知一二,都知道tcp处于传输层及三次握手可靠连接等,但是对于更为详细的四次撒手过程及tcp的状态位及包序号的计算问题可能不是很了解。在现场支持过程中,有时候会进行tcp包的分析,所以我们也需要对tcp协议做到熟悉了解。

当我们采用wireshark进行抓包时,我们会得到如下的截图,其中win代表了tcp的滑动窗口的大小,当win = 0时,意味着接收缓冲区慢,没办法继续接收数据,目前sdk的回放速度就是通过tcp的这种机制来控制码流数据接收的。


Tcp三次握手过程是为了保证连接的有效性。在抓包情况看,有如下的抓包代表着当前连接建立成功,这个过程对于大家来说应该是很熟悉的。

但在三次握手过程中,会出现一种叫做ddos工具,即攻击客户端在短时间内会伪造大量不存在的ip地址,向服务器不断发送syn包,服务器回复确认包,并等客户确认,由于源地址不存在,服务器需要不断的重发直到超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。不单纯是有目的的进行攻击,在赵琳的“半开连接限制和限制修改方法”这篇经验案例中就遇到了在三次握手过程中,因为访问这种攻击,系统采取一些手段导致我们网络无法正常连接的情况出现。

说完三次握手后,再说下四次撒手,对于四次撒手,可能大家对于这个交互就比较迷惘了。四次撒手的交互相对三次握手要赋值些。其交互流程如下:

 

其中上图的两种情况中第一种情况出现在其中一方请求关闭,第二种情况出现在服务端和客户端同时调用了关闭sock的请求出现的情况。但是这种交互流程在sdk和设备端的交互过程中都没有走,在sdk和设备端的交互中都是如下抓包的过程:

这种过程就是一种异常关闭连接的过程。因为在tcp在交互过程中常会出现一些意想不到的情况导致无法正常四次挥手关闭连接,如果不通过其他方式关闭连接,那么tcp连接一直存在着导致资源占用,因此tcp协议提供了reset报文来强制关闭。对于这种报文的出现,我们一开始的认识是因为我们调用Windows api的某个接口导致的。但关闭socket的接口只有两个,一个是closetsocket,另外一个是shutdown。经过网上查阅资料发现,这两个函数是不能完全控制报文发送的,

close-----关闭本进程的socket id,但链接还是开着的,用这个socket id的其它进程还能用这个链接,能读或写这个socket id

shutdown--则破坏了socket 链接,读的时候可能侦探到EOF结束符,写的时候可能会收到一个SIGPIPE信号,这个信号可能直到socket buffer被填充了才收到,shutdown还有一个关闭方式的参数,0 不能再读,1不能再写,2 读写都不能。

因为我们sdk发送reset报文的根本原因是因为缓冲区中还有数据未取出或者发送缓冲区还有数据未发送导致。

如果要做到优雅关闭socket,可以使用如下步骤:

(1)调用shutdown(s, SD_SEND),如果本端同时也接收数据时则执行第二步,否则跳到第4步。

(2)继续接收数据,

(3)收到FD_CLOSE事件后,调用recv函数直到recv返回0或-1(保证收到所有数据),

(4)调用closesocket,关闭socket句柄。

 

你可能感兴趣的:(常用tcp协议交互的分析解读及与socket编程之间的关系)