为什么TCP连接需要三次握手呢?
正经版本(原理阐述)
TCP连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫做客户(client),而被动等待连接建立的应用进程叫做服务器(server)。
假定主机A运行的是TCP客户程序,而B运行TCP服务器程序。最初两端的TCP进程都处于CLOSED(关闭)状态。
1.B的TCP服务器进程先创建传输控制块 TCB,准备接受客户进程的连接请求。然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。
2.A的TCP客户进程也是首先创建传输控制模块TCB,然后向B发出连接请求报文段,这时首部中的SYN = 1,同时选择一个初始序号seq = x。TCP规定,SYN报文段(即SYN = 1的报文段)不能携带数据,但要消耗掉一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态。
3.B收到连接请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中应把SYN位和ACK位都置1,ack = x + 1,seq = y。请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。
4.TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,ack = y + 1,seq = x + 1。这时,TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。
5.当B收到A的确认后,也进入ESTABLISHED状态。
上面给出的连接建立过程叫做三次握手(three-way handshake)。
为什么A还要发送一次确认呢?这主要是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。
考虑一种情况,即A发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达B。本来这是一个早已失效的报文段。但B收到此失效的连接请求报文段后,就误认为是A又发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了。采用三次握手的办法可以防止上述现象的发生。
非正经版本(加深理解)
我们可以用谈恋爱来模拟一下TCP三次握手过程。
假定A是女孩子,运行的是TCP客户程序,而B是男孩子,运行TCP服务器程序。
1.A对B说:“我喜欢你,我们在一起吧!”
2.B收到了,很开心,因为他也喜欢A,因此他对A说:“好啊,我也喜欢你,我们在一起吧!” 注意此时他们并不能建立恋爱关系!!!因为B虽然对A表明了态度,但是A却不一定收到了B的信息,因此A并不知道B是否同意了她的表白。
3.A收到了B的回复,非常开心,回复B说:“我收到啦,咱们可以一起愉快地玩耍啦!!”,这时恋爱关系才可以确定,因为A知道了B也是喜欢她的。
4.B收到了A的回复,也进入了恋爱状态。
考虑一种异常情况,A在一年前对B说:“我喜欢你,我们在一起吧!”,然而由于网络的阻塞B却没有收到。于是A重新发送了一次:“我喜欢你,我们在一起吧!”,B收到了,并与A按照上述流程建立了恋爱关系。然而,六个月以前他们分手了。今天B又收到了A的信息“我喜欢你,我们在一起吧!”(来自一年前的信息),非常开心,向A发送了“好啊,我也喜欢你,我们在一起吧!”,但是A收到后觉得莫名其妙,不予理睬,于是就不能恋爱成功,因为A此时并不想与B建立恋爱关系。采用三次握手的办法可以防止已失效的恋爱请求导致错误恋爱的发生。
懂了啵???