TCP连接与终止
TCP连接与终止
简介
我们都知道TCP连接是三次握手,那么这三次握手都发送了什么?
TCP连接断开的时候又变成了四次报文传递,这四次的意义又是什么呢?
三次握手
- 我们通过一个简单的程序构造了一次没有任何数据发送的TCP连接,下面我们来看一下wireshark抓到的数据.
45420->2000 [SYN] Seq=0
2000->45420 [SYN,ACK] Seq=0 Ack=1
45420->2000 [ACK] Seq=1 Ack=1
-
我们来分析一下三次握手都干了些什么
- 这样就很清楚的看到了,45420是我们的请求端,请求端首先发送一个SYN来建立45420->2000一侧的连接(Seq和ACK值我们稍后解释)
- 2000是我们的服务器端,服务器端向请求端发送ACK来确认第一个SYN已收到,发送SYN来建立2000->45420一侧的连接.
- 45420发送ACK表明2000发送的SYN已经收到
-
明确一个概念,真实的Seq是随机的,因为我们使用的是wireshark所以看到的Seq是相对的.
-
Seq的目的是为了标识数据的顺序.第一次我们通告了SYN的序号为0.随后返回的序号中ACK的值为1,也就是说通过将对端的序号加1TCP确认收到了该数据.
-
第二个Seq也为0,这个0标识的则是2000所发送的序号.随后同样将Seq+1我们得到了ACK的值.此时45420中的Seq变为刚刚收到的2000发来的ACK值.
-
简单来说,ACK=Seq+length+1 -> Seq=ACK(new)
四次断开
- 我们先来看一下wireshark抓到的断开的数据包
45420->2000 [FIN,ACK] Seq=1 Ack=1
2000->45420 [ACK] Seq=1 Ack=2
//Sleep 2 seconds
2000->45420 [FIN,ACK] Seq=1 Ack=2
45420->2000 [ACK] Seq=2 Ack=2
-
首先说明一点,TCP是一个面向连接的全双工的字节流协议.因为全双工的原因,每个方向都需要单独的关闭.
-
有了上面的概念,为什么是四次握手就显而易见了.45420发送FIN,ACK到2000声明关闭,2000回复ACK从而45420方向关闭了TCP连接.
我们在服务器程序中设定了Sleep(2s),所以我们可以看到,2000并不会因为45420发送了FIN就同步关闭自己那一端的TCP连接.
两秒钟后2000发送FIN,在接到ACK后关闭TCP连接. -
如果以全双工管道的概念来理解TCP的话,全双工意味着连接维护着两条半双工的TCP管道.那么我们在发送FIN之后会关闭其中一条,但是另外一条仍旧没有关闭.
也就是说,45420是可以继续收到数据,而2000也是可以继续发送的(依赖不同的实现)