原文:https://blog.csdn.net/wdscq1234/article/details/52389664
基本概念
ISN: 初始的序列号,Sequeue Number,TCP 协议栈为每一个封包都会分配一个sequence number,主要用来保证顺序的问题
MSS:最大报文长度,发送的报文不要超过这个值,一般情况下MTU-IP Header - TCP Header
ACK:确认序号,表明下一个需要接收的包的Sequeue number,可以通过这个来尽最大可能保证不丢包
Window Size: 滑动窗口,解决流量控制
三次握手
1.请求端先发送一个SYN包(图中的103包),告诉连接服务器端口及ISN,如下图Seq = 0,MSS = 1460(MTU = 1500) Window Size = 65535
2.服务器会对SYN包做一个回应,ACK = 1(103包的Seq + 1), 即期望获得Seq = 1的包,然后告知Windwos和MSS
3.客户端收到[SYN ACK]包,然后将Seq = 1发送一个ACK包,对服务器来的ACK进行确认
这样就完成了三次握手,成功建立了一个连接,接下来就可以正常发送数据了!![](https://i-blog.csdnimg.cn/blog_migrate/43326a09f9c35c898e548fd6315936a8.png)
说明:在TCPdump中看到的三次握手的seq number总是为0,但是实际上真实的协议栈不是这样的,ISN是一个随时间变化的值,不能是Hard Code,在这里如此实际上是Tcpdump做了优化,显示了一个相对的值,可以通过右键,Protocal option中的Ralative SeqNum取消掉即可。
下图是三次握手的示意图,X,Y就是一开始的ISN了
![](https://i-blog.csdnimg.cn/blog_migrate/6728579e912a5ad11c708536b894cf06.png)
对于Seq number是如何变化的,可以看下整个流的流量图,这里可以看到一点: 单独的ACK不会消耗Seq number,Seq Number的增加是和传输的字节数相关的,可以看到三次握手之后,客户端开始发数据,这个时候Seq = 1, 发了161长度的数据包,对方回复了一个ACK = 162,也就说162前面的我已经都收到,请发162及之后的数据,接着 服务器又回复了一个1340长度的数据包,客户端给予一个ACK = 1341的确认!
![](https://i-blog.csdnimg.cn/blog_migrate/95c880e1723d01bf1e5b53d6cac4b7cb.png)
四次挥手
终止一个连接要经过4次挥手,其实这个主要是由于TCP的半关闭造成的,TCP属于全双工的通讯,既能发又能收,当然可以关闭一部分,比如说让这个接口只能收不能发,这就是半关闭了,每一方都需要关闭,才能完成真正的关闭!
1)一般情况下客户端首先关闭,即发起一个FIN包,首先执行关闭的一端叫主动关闭,另一方成为被动关闭
2)服务器收到客户端的FIN包之后,会发会一个ACK包,确认序号为收到的需要加一,说明FIN包和SYN包一样都占用一个序号
3)客户端收到ACK包之后,说明客户端已经半关闭了,这个时候只能接收数据包,但是不能发送数据包
4)如果服务器也完成了发送数据需要关闭链接,TCP端就会发送一个FIN包给客户端
5) 客户端收到FIN包之后,就回复一个ACK表示收到,连接关闭
连接超时
很多状况下,客户端无法连接到服务器上,基本都是发送SYN包,服务器端由于一些故障,没有回复SYN ACK,可以看一个实验的tcpdump结果,重新发送SYN包的事件间隔分别是 1s 2s 4s 8s 16s 32s,这个规律很好寻找,时间按照2^n次方的规律递增!