对于三次握手的疑问

三次握手的第三次握手发送ACK能携带数据吗?如何携带?怎样体现的呢?

作者:车小胖
链接:https://www.zhihu.com/question/66407996/answer/242152945
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

人类先发明了电话,当电话原理成熟了,上世纪中后叶又出现了TCP/IP,TCP协议几乎就是模仿电话原理的,为了更好学习TCP,我们要学习电话的基本原理。

三次握手的过程
第一次

上海的老王给北京的老张打电话,拨号码
010-68886xx8

老王电话机与电信局之间的电话线,其实有两个信道:信令信道 + 语音信道

当老王拿起电话,拨010-68886xx8,这个号码通过信令信道传到了电信局,同时将语音信道(DS0)保留,为了稍后的通信做语音信道预留

电信局根据这个号码做路由查找,找到其上一级的交换机,通过信令信道将010-68886xx88转发给上一级交换机,同时和上一级协商好,预留一个DS0语音信道,为了语音传输。

这样一级级转接,最终号码转接到北京老张的电话机,振铃,北京电信局与老张电话机之间预留一个DS0语音信道,为了语音传输。

第二次
老张拿起电话的那一刻,一个“Connected”信令顺着来时的信令信道(一跳、一跳)传输到老王的电话机。

第三次
老王电话机通常还会回复一个“ACK”给对方,以示接到对方的“Connected”。

语音传输
当老张拿起电话的那一刻,端到端的语音信道已经预留好了,一般为DS0= 64Kbps,这条端到端信道其实是由多条 hop-2-hop信道串联而成的。

此时双方可以自由说话,语音数据会从保留的语音信道流淌到对方。

从以上的描述来看,信令数据、语音数据是在自己独立的信道里传输,大家井水不犯河水,互不干涉。

TCP
TCP模仿电话原理,也有自己的信令数据、应用层数据,那哪些是信令数据呢?
SYN
ACK
RST
PSH
URG
FIN

依靠这六个信令状态位,与对方
1)建立连接SYN
2)重置连接RST
3)拆除连接FIN

那什么是应用层数据呢?就是TCP的服务对象,比如Http。

TCP也想使用电话里的双信道,但TCP所依赖的IP网络没有信道的概念,完全是一个共享网络的模式。

TCP没有双信道使用,退而求其次,只要信令数据、应用数据放在独立的IP包传输到对方就好,这就是大家最熟悉的TCP工作模式:

1)三次握手建立连接
2)数据传输
3)四次握手拆除连接

三次握手最后一个消息是客户端发过来的ACK,如果让应用层数据与这个信令数据合二为一,可以减少发送的IP包的数目,还可以提高效率,何乐不为呢?

TCP协议的制定者,为了提高效率,减少IP包的数目,最大可能地将信令数据、应用数据合二为一,各位同学通过抓包,可以看到一个TCP连接,除了第一个SYN包,每个TCP报文都有ACK信令,这就是合二为一的结果!

第三次握手,是客户端为了告诉服务器,我已经收到了你发送的SYNC + ACK报文,此时这个报文只带ACK标志,SYNC标志没有。

客户端发送这个报文之后,就进入established状态了。服务器收到这个报文之后,也进入established状态。

TCP标准规定,第三次握手的报文,可以携带数据。因为此时客户端已经处于established状态了呀。

假设第三次握手的报文的seq是x+1,

如果有携带数据,下次客户端发送的报文,seq=服务器发回的ACK号。

如果没有携带数据,那么第三次握手的报文不消耗seq。下次客户端发送的报文,seq序列号还是和第三次握手的报文的seq一样,为x+1。这是因为,seq和报文中的数据在整条数据流流中的位置是一一对应的。如果报文没有携带数据,那么seq当然也不会更新。

原文地址:https://www.cnblogs.com/mrwuzs/p/8031161.html