前几天被一个好友问到了这个问题,让我的思绪回到了当年的“计算机网络与原理”那门课程……,是啊,为什么握手是三次,而不是两次,或者四次呢?
先来一张搞笑图哦~
如图所示,是美国三位总统的三次握手,哈哈,为什么不是两次,为什么不是四次,这个问题又在我脑子里回荡了……
首先,我看了下网上资料,引用了了两本书中的定义:
1.解决“网络中存在延迟的重复分组”问题。
2.“为了防止已失效的链接请求报文段突然又传送到了服务端,产生错误”。
3.保证链接的是双工的,可靠更多的是通过重传机制保证。
除了第3点,其他的看着比较懵逼,究竟是啥意思哩???
之后带着上述3点定义,我又去网上找答案,之后思路渐渐清晰起来了,看图:
首先,这里有两个端的概念,1.Client端,2.Server端,连接建立就是C端和S端。
握手的过程:
1. C端发送syn包(syn = j)到服务器,进入SYN_SEND状态,等待S端确认。
2. S端收到syn包,确认C端的syn(ack=j+1),向C端发送一个syn包(SYN+ACK),进入SYN_RECV状态。
3. C端收到SYN+ACK包,向服务器发送确认包ACK(ack=k+1),之后C和S进入ESTABLISHED状态,完成三次握手。
下面解释一下,为什么是三次握手?
1.从性能和安全角度
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。
2.从信道可靠性角度
这个问题的本质是, 信道不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的. 请注意这里的本质需求,信道不可靠, 数据传输要可靠. 三次达到了, 那后面你想接着握手也好, 发数据也好, 跟进行可靠信息传输的需求就没关系了. 因此,如果信道是可靠的, 即无论什么时候发出消息, 对方一定能收到, 或者你不关心是否要保证对方收到你的消息, 那就能像UDP那样直接发送消息就可以了.”。这可视为对“三次握手”目的的另一种解答思路。
对比三次握手和两次、四次区别
1.四次握手过程:
1)C发送同步信号SYN + C‘s initial sequence number
2)S确认收到C的同步信号,并记录C‘s ISN到本地,命名S‘s ACK sequence number
3)S发送同步信号SYN + S's initial sequence number
4)C确认收到S的同步信号,并记录S‘s ISN到本地,命名C‘s ACK sequence number
显然,2和3两步可以合并,只需要3次握手,可以提交效率和速度。
2.两次握手过程:
1)A发送同步信号SYN + A‘s initial sequence number
2)B发送同步信号SYN + B's initial sequence number + B's ACK sequence number
问题,A与B就A的初始化序列号达成一致,但是B无法知道A是否已经收到自己的同步信号,如果同步信号丢失,AB就B的初始化序列号将无法达成一致。
That's all.