文章目录
计算机网络之TCP三次握手
1.TCP三次握手过程
1.第一次握手:
客户端请求建立连接,客户端将标志位SYN置为1;
主机A发送位码为SYN=1,ACK=0,随机产生一个随机数seq number= j的同步报文(也是数据包)到服务器(TCP规定SYN=1时不能携带数据但要消耗一个序号);
客户端进入SYN_SENT状态(即等待状态),等待服务器确认,服务端由客户端发送的SYN=1知道,客户端要求建立联机;
2.第二次握手:
服务端收到连接请求报文(也是数据包)后由标志位SYN=1知道客户端请求建立连接,主机B收到请求后要确认联机信息;
服务端将标志位SYN和ACK都置为1;
向A发送确认号ack number(=客户端的seq+1=j+1)、及SYN=1,及ACK=1,随机产生一个随机数seq=K作为初始序列号的同步确认报文并将该数据包发送给客户端以确认连接请求;
此时服务器进入SYN_RECV状态
3.第三次握手:
主机B收到后确认收到的ack值与发送给A的seq+1是否相等和ACK是否为1来判断连接是否建立成功。
客户端收到确认后,检查ack是否为J+1,ACK是否为1;
如果正确客户端将标志位ACK置为1;
如果正确客户端会再发送ack number(=Server的seq+1=K+1)、ACK=1,并将该确认报文(数据包)发送给服务端,
服务端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务端进入ESTABLISHED状态,完成三次握手,随后客户端与服务端之间可以开始传输数据了。
注:理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去
思路: TCP 连接的三次握手机制,最重要的知识点,必须得会,通讯过程以及客户端、服务器的对应的状态都需要记住哈。
TCp 提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的就是同步连接双方的序列号和确认号并交换 TCP 窗口大小信息。
流程:
● 第一次握手 (发送连接请求报文SYN=1, 初始序号随机seq=x,ACK=0),发送完毕后,客户端就进入 SYN_SENT 状态
● 第二次握手 (发送连接确认报文SYN=1, ACK=1, seq=y, ACKnum=x+1), 发送完毕后,服务器端就进入 SYN_RCV 状态。
● 第三次握手 (发出连接确认报文ACK=1,ACKnum=y+1,序号seq=x+1),发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态。
注:ACK也好,ack也好,只不过是个代号而已
ACK是确认值(Acknowledgement),为1便是确认连接。
ack是确认编号(Acknowledgement Number),即接收到的上一次远端主机传来的seq然后+1,再发送给远端主机。提示远端主机已经成功接收上一次所有数据。
2.TCP三次握手原因,而不是两次
主要有三个原因:
第一个原因:三次握手才能让双方均确认自己和对方的发送和接收能力都正常
1.第一次握手:客户端发送包,服务端收到了
根据第一次握手,服务端得出结论:客户端的发送能力、服务端的接收能力是正常的。
2.第二次握手:服务端发包,客户端收到了
根据第一次握手以及第二次握手,客户端能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的;
不过此时服务端并不能确认客户端的接收能力、以及服务端的发送能力是否正常
3.第三次握手:客户端发包,服务端收到了
根据第一次握手及第二次握手以及第三次握手,服务端能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
因此,需要三次握手才能确认双方的接收与发送能力是否正常
第二个原因:防止已过期的连接请求报文突然又传送到服务器,因而产生错误和资源浪费
为什么A还要发送一侧确认呢?这主要是为了防止已失效的连接请求报文突然又传送到了B,因而产生错误。
所谓“已失效的连接请求报文段”是这样产生的。双方两次握手即可建立连接的情况下,A发出连接请求,但因连接请求丢失而未收到确认。于是A再次重传一次连接请求。后来收到了确认建立了连接。数据传输完毕后,就释放了连接。A供发送了两个连接请求的报文段,其中第一个丢失,第二个到达了B。没有“已失效的连接请求报文段”。
现假定出现一种异常情况,即A发出的第一个连接请求报文段并没有丢失,而是在某些网络节点长时间滞留了,以致延误到连接释放以后的某个时间才到B。本来这是一个已失效的报文段。但是B收到此失效的连接请求报文段后,就误认为是A有发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了。
由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立了,并一直等待A发来数据。B的许多资源就这样拜拜浪费了。
采用三次握手的办法可以防止上述现象的发生。例如在刚才的情况下,A不会向B的确认发出确认。B由于收不到确认,就知道A并没有要求建立连接。
第三个原因:告知对方自己的初始序号值,并确认收到对方的初始序号值
TCP 实现了可靠的数据传输,原因之一就是 TCP 报文段中维护了序号字段和确认序号字段,通过这两个字段双方都可以知道在自己发出的数据中,哪些是已经被对方确认接收的。这两个字段的值会在初始序号值得基础递增,如果是两次握手,只有发起方的初始序号可以得到确认,而另一方的初始序号则得不到确认。
另一种解释:
这个问题的本质是, 信道不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的. 请注意这里的本质需求,信道不可靠, 数据传输要可靠. 三次达到了, 那后面你想接着握手也好, 发数据也好, 跟进行可靠信息传输的需求就没关系了. 因此,如果信道是可靠的, 即无论什么时候发出消息, 对方一定能收到, 或者你不关心是否要保证对方收到你的消息, 那就能像UDP那样直接发送消息就可以了”。这可视为对“三次握手”目的的另一种解答思路。
3.TCP三次握手原因,而不是四次
因为三次握手已经可以确认双方的发送接收能力正常,双方都知道彼此已经准备好,而且也可以完成对双方初始序号值得确认,也就无需再第四次握手了。
第一次握手:服务端确认“自己收、客户端发”报文功能正常。
第二次握手:客户端确认“自己发、自己收、服务端收、客户端发”报文功能正常,客户端认为连接已建立。
第三次握手:服务端确认“自己发、客户端收”报文功能正常,此时双方均建立连接,可以正常通信。
4.TCP三次握手能携带数据吗
答:其实第三次握手的时候,是可以携带数据的;但是,第一次、第二次握手不可以携带数据
原因:假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。
5.三次握手连接阶段,最后一次ACK包丢失,会发生什么
服务端:
*第三次的ACK在网络中丢失,那么服务端该TCP连接的状态为SYN_RECV,并且会根据 TCP的超时重传机制,会等待3秒、6秒、12秒后重新发送SYN+ACK包,以便客户端重新发送ACK包。
*如果重发指定次数之后,仍然未收到 客户端的ACK应答,那么一段时间后,服务端自动关闭这个连接。
*客户端:
客户端认为这个连接已经建立,如果客户端向服务端发送数据,服务端将以RST包(Reset,标示复位,用于异常的关闭连接)响应。此时,客户端知道第三次握手失败。
6.TCP 握手为什么是三次,为什么不能是两次?不能是四次?
思路: TCP 握手为什么不能是两次,为什么不能是四次呢?为了方便理解,我们以男孩子和女孩子谈恋爱为例子:两个人能走到一起,最重要的事情就是相爱,就是我爱你,并且我知道,你也爱我,接下来我们以此来模拟三次握手的过程:
为什么握手不能是两次呢?
如果只有两次握手,女孩子可能就不知道,她的那句我也爱你,男孩子是否收到,恋爱关系就不能愉快展开。
为什么握手不能是四次呢?
因为握手不能是四次呢?因为三次已经够了,三次已经能让双方都知道:你爱我,我也爱你。而四次就多余了。
总结:
确保可靠的通信通道,让双方都确认对方和自己的接收和发送功能是正常的。
将三次握手通俗的说。
1.第一次握手,Server知道Client的发送能力和自己的接收能力是正常的。
2.第二次握手,Client知道Server的发送和接收能力和自己的发送和接收能力是正常的,但是Server还不知道我的接收和他的发送能力正常与否。
3.第三次握手,Client回馈,让Server知道自己的发送能力和Client的接收能力正常。