三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。
但是为什么一定要进行三次握手来保证连接是双工的呢,一次不行么?两次不行么?我们举一个现实生活中两个人进行语言沟通的例子来模拟三次握手。
第一次对话:
老婆让甲出去打酱油,半路碰到一个朋友乙,甲问了一句:哥们你吃饭了么?
结果乙带着耳机听歌呢,根本没听到,没反应。甲心里想:跟你说话也没个音,不跟你说了,沟通失败。说明乙接受不到甲传过来的信息的情况下沟通肯定是失败的。
如果乙听到了甲说的话,那么第一次对话成功,接下来进行第二次对话。
第二次对话:
乙听到了甲说的话,但是他是老外,中文不好,不知道甲说的啥意思也不知道怎样回答,于是随便回答了一句学过的中文 :我去厕所了。甲一听立刻笑喷了,“去厕所吃饭”?道不同不相为谋,离你远点吧,沟通失败。说明乙无法做出正确应答的情况下沟通失败。
如果乙听到了甲的话,做出了正确的应答,并且还进行了反问:我吃饭了,你呢?那么第二次握手成功。
通过前两次对话证明了乙能够听懂甲说的话,并且能做出正确的应答。接下来进行第三次对话。
第三次对话:
甲刚和乙打了个招呼,突然老婆喊他,“你个死鬼,打个酱油咋这么半天,看我回家咋收拾你”,甲是个妻管严,听完吓得二话不说就跑回家了,把乙自己晾那了。乙心想:这什么人啊,得,我也回家吧,沟通失败。说明甲无法做出应答的情况下沟通失败。
如果甲也做出了正确的应答:我也吃了。那么第三次对话成功,两人已经建立起了顺畅的沟通渠道,接下来开始持续的聊天。
通过第二次和第三次的对话证明了甲能够听懂乙说的话,并且能做出正确的应答。
可见,两个人进行有效的语言沟通,这三次对话的过程是必须的。
同理对于TCP为什么需要进行三次握手我们可以一样的理解:
为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。
第一次握手:客户端发送SYN包(syn=x)给服务端,此时客户端进入SYN_SEND模式
第二次握手:服务端收到客户端传递的SYN包之后,发送ACK包(ack=x+1)和SYN包(syn=y)给客户端,此时服务端进入SYN_RECEIVED模式
第三次握手:客户端收到服务端的SYN+ACK包,发送ACK(ack=y+1)给服务端,此时双方进入ESTABLISHED状态。
tcp连接建立之后,就可以发送数据了。理想情况下,只要双方不主动断开连接,连接一直存在。
四次挥手
第一次挥手:主动关闭方发送FIN包给被动关闭方,此时主动关闭方不会再发送数据给被动关闭方,但是FIN包之前的数据没有收到ack请求的话再次发送。可以继续接受数据。
第二次挥手:被动关闭方发送ACK数据包给主动关闭方,确认序列号为收到序列号+1,表示我知道你不会再给我发送数据了。
第三次挥手:被动关闭方发送FIN包给主动关闭方,表明不会再发送数据,但是可以发送FIN之前的数据,如果没有收到ack请求的话。
第四次挥手:主动关闭方发送ACK包给被动关闭方,连接断开