前言
如果你学过网络基础知识,那么你一定对TCP三次握手不陌生。今天我想用通俗的话来给大家讲一讲TCP三次握手和四次挥手。毕竟,这个知识点在面试时被问到的概率很高!
TCP特点
① 面向连接
TCP是面向客户端和服务器端连接的通讯协议,使用它可以将客户端和服务器端进行连接。数据通信之前,必须要有一个连接通道建立。
② 可靠性
是指无论网络环境多差,TCP都可以保证信息一定能够传递到接收端。TCP之所以可以保证可靠性主要得益于两个方面,一个是“状态性”,另一个是“可控制性”。所谓状态性是指TCP会记录信息的发送状态,例如,哪些数据收到了、哪些数据没收到等状态信息都会被记录;可控制性是指TCP会根据状态情况控制自己的行为,比如当TCP意识到丢包了就会控制重发此包,这样就实现了TCP的可靠性。 总之,TCP可以很好地处理传输过程中数据包丢失的情况,它会重复发送包,这个特性很关键。
③ 传输单位为数据段
是指TCP在数据传输时,传送的每一个数据包里的数据只是一个数据段单元,并非完整数据,比如,要传送一个1MB的文件,整个文件会被切割成诸多数据段,然后再进行传输。 由于数据段大小受应用层传送给的报文大小和所途径网络中的MYU值大小决定,所以每次发送的TCP数据段大小是不固定的。在一个具体的网络中,有一个MSS(Maximum Segment Size,即最大数据段大小),最小的和数据段可能仅有21字节(其中20字节属于TCP数据段头部,数据部分仅1字节)。
④基于字节流
说到字节流,不得不提一下UDP的传输,UDP传输是基于报文的,简单点理解,UDP传输一个消息,需要将整个消息封装成一个数据包,然后进行传输。而TCP不一样,它会把整个消息切割成若干段,然后每一个段再被封装成数据包,逐一传输。总之,TCP不像UDP那样以一个个报文独立地进行传输,而是在不保留报文边界的情况下以字节流方式进行传输。TCP三次握手过程
了解了TCP的特点后,再来看TCP三次握手就容易理解为何要三次,而不是两次啦。
一开始客户端和服务端都是CLOSED状态,就好比他们两个彼此相互不认识,谁都不理谁。下面为了更好理解三次握手,我把客户端叫做小客,服务器叫做小服。
有一天小客需要小服帮忙,于是小客首先跟小服打招呼:你好小服,我需要你帮助,可以帮我吗?(客户端发送SYN=1,seq=x,这个x是一个随机数) 小服收到消息后,会回一个反馈给到小客:你好小客,我可以帮助你啊,那我要如何帮你呢?(服务端发送SYN=1,ACK=1,同时发送seq=y,ack=x+1,这里的ack为客户端发送的seq数值加1) 小客收到小服的反馈后,很高兴,于是又跟小服回了一句:谢谢你小服,我需要你帮我做……(客户端再次跟服务端发送ACK=1,seq=x+1,ack=y+1)。 小服再次收到小客的反馈后,小服就开始帮小服做事情了,从此成为了好基友!做一个简单总结:
第一次握手:客户端发送 SYN 报文,并进入 SYN_SENT 状态,等待服务器的确认;
第二次握手:服务器收到 SYN 报文,需要给客户端发送 ACK 确认报文,同时服务器也要向客户端发送一个 SYN 报文,所以也就是向客户端发送 SYN + ACK 报文,此时服务器进入 SYN_RCVD 状态;
第三次握手:客户端收到 SYN + ACK 报文,向服务器发送确认包,客户端进入 ESTABLISHED 状态。待服务器收到客户端发送的 ACK 包也会进入 ESTABLISHED 状态,完成三次握手。
TCP四次挥手
当客户端和服务端通信完毕后,需要断开连接,释放资源。在正式断开连接之前,客户端和服务端会出现几个状态,先看四次挥手状态图:
我们还拿刚才小客和小服来举例,小客的事情在小服的帮助下得到了圆满结束,小客对小服非常感激,这一天小客跟小服提出了感谢。
小客:你好小服,我的事情在你的帮助下终于完成了,感谢你的帮忙,后面暂时不需要你的帮助啦。(FIN=1 seq=u)
小服:收到,小客,不用客气啦。这阵我也太累了,是该休息一下啦,那我们就后会有期吧?(ACK=1 seq=v ack=u+1; FIN=1 seq=w ack=u+1)
小客:再次感谢,后会有期!(ACK=1 seq=u+1 ack=w+1)
之后小客和小服就没有再联系了。
再来做个总结吧:客户端发送断开TCP连接请求的报文,其中报文中包含seq序列号,是由发送端随机生成的,并且还将报文中的FIN字段置为1,表示需要断开TCP连接。(FIN=1,seq=x,x由客户端随机生成);
服务端会回复客户端发送的TCP断开请求报文,其包含seq序列号,是由回复端随机生成的,而且会产生ACK字段,ACK字段数值是在客户端发过来的seq序列号基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP断开请求已经得到验证。(FIN=1,ACK=x+1,seq=y,y由服务端随机生成);
服务端在回复完客户端的TCP断开请求后,不会马上进行TCP连接的断开,服务端会先确保断开前,所有传输到A的数据是否已经传输完毕,一旦确认传输数据完毕,就会将回复报文的FIN字段置1,并且产生随机seq序列号。(FIN=1,ACK=x+1,seq=z,z由服务端随机生成);
客户端收到服务端的TCP断开请求后,会回复服务端的断开请求,包含随机生成的seq字段和ACK字段,ACK字段会在服务端的TCP断开请求的seq基础上加1,从而完成服务端请求的验证回复。(FIN=1,ACK=z+1,seq=h,h为客户端随机生成)
TCP连接中的状态说明
TCP三次握手和四次挥手过程中,客户端和服务端出现了多个TCP连接状态,下面我来做一个列举。
LISTEN:服务端上起了服务就会监听一个端口(例如SSHD服务监听22端口),等待客户端来连接它。
SYN_SENT:客户端想要连接服务端,先打招呼,也就是三次握手时的第一次,它把请求发出去后,就变成了这个状态,表示等待服务端的确认。
SYN_RECEIVED:服务端接收到了客户端的请求,之后需要反馈给客户端确认信息,并且同时也要把自己的请求信息一起发给客户端,此时就会变成SYN_RECEIVED状态。
ESTABLISHED:经过三次握手后,客户端和服务端相继变成ESTABLISHED状态,表示双方建立了连接。只有双方都是该状态,才可以顺利传输数据。
FIN_WAIT_1:客户端和服务端传输完数据后,总有一方需要主动发起关闭连接,这个FIN_WAIT_1状态出现在主动关闭方。当它发起关闭连接的请求后,就会变成此状态。它需要等待对方的确认。
FIN_WAIT_2:主动关闭方收到被动关闭方的确认信息后,就会变成此状态。
CLOSE_WAIT:被动关闭方收到主动方的关闭请求后,会发出确认信息,确认信息发出后就出现了CLOSE_WAIT。
LAST_ACK:被动关闭方除了发送确认信息外,还需要发送关闭确认信息给对方,这个信息发送完毕后,就会成为LAST_ACK状态,此时被动关闭方只需要等待主动关闭方的一个回馈确认信息。
TIME_WAIT:主动关闭方将最后一次的确认信息发送给被动关闭方,就会处于TIME_WAIT状态,该状态只出现在主动关闭方,它只需等待一个时间就会彻底关闭,这个等待的时间为2*MSL(Maximum Segment Lifetime,报文最长存活时间)。因为它需要一个等待时间,所以在Linux系统里,这个状态是最常见、最多的状态。
CLOSING:几乎看不到的状态,表示正在关闭连接,这个是瞬时完成的。
CLOSED:彻底关闭连接的状态(这是为方便描述假想的状态,实际不存在)
审核编辑:刘清
免责声明:文章内容来自互联网,本站不对其真实性负责,也不承担任何法律责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:讲一讲的TCP三次握手和四次挥手-tcp三次握手的工作原理 https://www.yhzz.com.cn/a/4753.html