接上篇 建立TCP连接——三次握手,我们讲了什么是三次握手。可能有同学存在和老范一样的疑问,为什么是三次握手啊?
这个问题,80%的面试官会问,划重点吧。
今天,老范就结合这张图进行讲解,可能会有点难,我会尽力结合生活中的例子进行解释。
1.为什么要是三次?
确保稳妥。
我们先看如果是一次握手会怎么样。
如果是一次握手,你压根就不知道对方爱不爱你。
如果说客户端在发送链接请求(也就是SYN=1)后,不等服务端回复就开始传输数据给服务端,那真的会很惨:首先,客户端不知道服务端有没有收到它的连接信息;其次,客户端发送数据后,就需要等待服务端进行响应,这一等可能就是一辈子,白白浪费了资源。
更可悲的是,服务端可能压根就不知道这回事。
好比上图的情景,二狗约了小花,没等小花回复就自作主张奔到她家去了。人家小花压根就不知道他要来以及他是谁。二狗不白去了么。。。
我们再看如果是两次握手会怎么样。
如果是两次,会导致服务端与客户端阴差阳错,擦肩而过悔恨终生。
简直太虐心了。
客户端发出链接请求seq=x,服务器端收到并回复确认码(ack=x+1),同时发送自己的序号seq=y,这时候似乎已经明确了两人的关系,但是却忽略了一个很大的问题:客户端有没有收到服务端的消息。
好比短信中提到的,小花告诉二狗,可以去她家玩,并且说今天会在家里等他。但是二狗显然没有确认这条消息,导致小花白白等了一晚上。
计算机网络通信中,情况要比这复杂得多。比如,当客户端与服务端处于不稳定的网络状态时,客户端发出了SYN=1,ack=0的链接请求,告知服务端,我要泡你,,不是,我要链接你了。可是由于网络不稳定,这段话延迟了,没有及时的送到服务端。
客户端等啊等,等了一段时间(注意,这里是个阈值,也就是说超过这个时间,客户端会重新发送链接请求给服务端),没收到服务端反馈,他就又重新发了一条请求链接过去,同时宣布上一条请求消息作废。
可千不该万不该,就在这一瞬间,之前迷失在网络中的那条延迟的消息传送到服务端了,服务端不知道客户端已经重新发了消息啊,于是就赶紧传送确认码以及自己的序列码给客户端。
也就是说,客户端发了两条请求链接,在某一刻收到了服务端发来的确认消息。大家心里应该清楚,这个回复不是对第二条请求链接的回复。客户端门口的保安打开一看,卧槽不对,服务端怎么回了一条我已经作废的消息接收确认啊,于是置之不理。专心等第二条请求链接的回复。
这个时候呢,客户端发送的第二条(也就是在第一条作废之后发送的那一条)请求链接到了服务端门口,门口保安一看,卧槽不是回过了么,怎么又来一个,置之不理。专心等待客户端发送数据过来。
客户端等了一段时间,没收到回复,就又发了一条请求链接。
服务端等了一段时间,没收到数据传送过来,就又发了重发一条回复。
从此,客户端与服务端进入死锁状态。各自都在等待对方,却不知早已注定没有结果。
虐心啊。
所以必须等待客户端的回复确认才能进行正常通信。
为什么不是四次握手呢?
你告诉我,是不是摸人家手上瘾。
在这里做一下拓展,什么是SYN、seq、ack。
SYN=1代表着这是一个请求链接,或者接受请求链接,好比自报家门吧,没什么要说的。
seq:这是一个随机序号,每次都不一样。
ack:确认码。你会发现,当服务端回复确认信息给客户端时,传了一个ack=x+1。x是什么,x是客户端发送的随机码seq。这就是服务端要告诉客户端,你传数据的时候啊,在x上加1