谈到TCP, 相信大家都不陌生,可能会想到网络的七层模型、TCP/IP、UDP等等,TCP(Transmission Control Protocol) 是一种面向连接的、可靠的(区别于UDP 的不可靠)、基于字节流的传输层(七层模型中的传输层)通信协议,支持超时重传,流量控制,拥塞控制等复杂功能,也就是说它是用来通信的,那它通信的过程是什么样的呢?今天就来了解下。
想想我们的日常通信场景,比如我和舍友的日常,我俩下班后想‘通信’了,主要是分为三步,第一步,[建立连接]–其中一方表达想聊天(通常是我),双方打开门(我俩两个房间);第二步,[数据传输]–说话吧啦啦啦一通;第三步,[断开连接]–说完了,互道晚安或拜拜,关门;这就是我们通信的方式,那类比于传输层通信tcp 来说,步骤是一样的,分为三个阶段:
建立连接(TCP三次握手)
数据传输
断开连接 (TCP四次挥手)
当应用层的一个程序想发送一个数据包给另外一个应用层的程序时,传输层接收到应用层传过来的数据包,会根据软件的协议(TCP/UDP) 会在该数据包的前面添加一个TCP/UDP 头部,包含了源端口号和目的端口号及其它信息等,传输层会把‘TCP/UDP头部+数据包’ 发送给网络层;
备注:因上面说到两个ACK,防止表达混淆,特在此说明ACK表示确认标志,ack表示确认号。
第一次握手
A向B发送建立连接请求: SYN=1, 发送自己的序号SEQ=x,发送之后处于SYN-SENT(同步已发送) 状态,等待接收方的确认;
第二次握手
B收到请求信息,如果同意建立连接(SYN=1),则发送确认报文段(ACK=1),确认收到的A的序号(ack=x+1),同时发送自己的序号SEQ=y,发送之后处于SYN-RCVD (同步收到)状态;
第三次握手
A 收到B 发来的ACK+SYN后,进行确认,发送确认信息ACK=1,确认收到B的序号ack = y+1,发送自己的序列号SEQ=x+1 ,发送之后A处于ESTABLISHED( 已建立连接)状态,当B 收到A的确认时,也进入ESTABLISHED( 已建立连接)状态。
因为TCP协议是一个全双工的、可靠的通信协议,为了实现可靠的双向通信,需要三次握手;
因为通信是双向的(可以类比为一个双向车道,在这个车道上,任何一方既可以是发送方,又可以是接收方),发送方和接收方都需要确认自己发送的数据包是否都被接收方收到,这个通过对序号(SEQ)的确认(ACK)来实现的,当没有收到时,需要重发(失败重传),而为了双方确认,最省力的办法是三次握手。
也可以理解为通信的双方要确认对方和自己都是靠谱的人,才会一起合作干大事。下图中体现了双方需要确认自己和对方的收发信能力过程,确认自己和对方都是有能力的,才会继续进行数据的传输。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lpgYkIgT-1631716486842)(/Users/zhangting/Desktop/tcp三次握手能力确认.png)]
《计算机网络》中有提到三次握手是为了防止已失效的连接请求又传送到服务器端,因而产生错误。大概意思是发送方的一次SYN建立连接请求因网络问题等原因长时间滞留,导致该请求发送方和接收方到第二次通信完成连接释放后才到达接收方,但此时接收方以为是发送方传来的一次新的连接请求,于是发出了确认,至此连接成功建立了,但这是接收方的想法,对于发送方来说,它并没有要建立连接的想法,所以接收方就是一直在等待发送方的通信,有点像单相思,接收方会一直耗费自己的资源。
这也不行啊,接收方决定不能继续等下去了,他需要发送方来确认此次的SYN 的有效性,如果无效,会回复一个reset 报文,使接收方重新处于listen状态, 这才有了第三次握手,避免了资源的浪费和信息的错误传送
本部分将重点介绍数据传输的问题及对应的解决机制,放在后续博客中。
爱情诚可贵,自由价更高。来学习专业的四次挥手:
第一次挥手
A向B发送断开连接的请求: FIN=1,发送自己的序号SEQ=u, 并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1 (终止等待1)状态;
第二次挥手
B收到A发来的信息,发送确认信息 ACK=1,确认收到A的序列号ack = u+1,同时发送自己的序列号SEQ=v, B进入CLOSE_WAIT(关闭等待)状态。
TCP服务器通知高层的应用进程,A不会再发数据过来,B也不会接收A方向的数据,A到B的连接被动关闭,连接就释放了;
A收到B的信息后,进入FIN_WAIT2( 终止等待2)状态,接受B发送的最后的数据,并且等待B的释放连接报文;
第三次挥手
B 将最后的数据发送完后,向A发送连接释放请求: FIN=1及确认信息和序号信息: ACK=1,SEQ=w(很可能又发送了一些数据),ack=u+1,B进入LAST_ACK(最后确认)状态,等待A的最后一个ACK;
第四次挥手
A收到B的释放连接请求后,发出对信息的确认:ACK=1,ack=v+1,自己的序列号SEQ=u+1,A进入TIME_WAIT(时间等待状态),会等待2MSL(Maximum Segment Lifetime,报文最大生存时间),如果没有收到B的ACK,认为B已经断开了连接,进入了CLOSED (关闭)状态,于是自己也断开连接,进入CLOSED状态;
B 收到A 发来的ACK报文后,断开连接,进入CLOSED状态;
TCP协议是一个全双工通信协议,双方都要确认自己没有信息发送给对方了才会断开连接,前两次挥手用于断开AtoB方向上的连接,后两次挥手用于断开BtoA方向上的连接;
握手需要三次,第二次握手时,B 向A发送了SYN+ACK,用来应答和同步;而挥手时,B因为可能还有内容发送,并不会马上发送FIN ,只能先发送ACK ,等B所有的报文发送完了再发送FIN,所以需要四次;
为了确保A最后一次的ACK 信息能够到达B,使B正确及时地关闭连接;
在2MSL的时间内,如果A最后一次的ACK丢失了,B将会重复发送FIN 信息,A将会再次发送ACK,并再次计时等待2MSL; 如果A在进入TIME_WAIT状态后立即进入CLOSED状态,当ACK在传输过程中丢失的话,因为A 已经关闭了,B重发FIN也不会收到回应,B将永远无法正常关闭;
当A等待2MSL后,没有再次收到FIN,认为ACK已经被B 成功接收,则可以放心地断开连接了;
《码农翻身》
https://blog.csdn.net/daocaoren1543169565/article/details/80535949
https://www.cnblogs.com/huigelaile/p/10938857.html
https://blog.csdn.net/lengxiao1993/article/details/82771768
https://www.zhihu.com/question/24853633/answer/2025912497
https://www.cnblogs.com/bj-mr-li/p/11106390.html
https://zhuanlan.zhihu.com/p/86426969
https://mp.weixin.qq.com/s/D-29Y7UJqgBUEMc3BRTw5Q
这篇文章陆陆续续地写了好久,希望路过的你喜欢ღ( ´・ᴗ・` )。