TCP三次握手

TCP的连接建立

         TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP报文段,即需要客户端和服务器端总共发送三个包。

         三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换TCP窗口大小信息。在Socket编程中,客户端执行connect()函数时,会触发三次握手过程。

         假设主机A运行的是TCP客户程序,而B运行的是TCP服务器程序。最初时两端的TCP进程都处于CLOSED状态。一旦有连接需要建立,A主动打开,B被动打开。

         一开始,B的服务器进程首先创建传输控制块(TCB),准备接受客户端进程的连接请求。然后服务器就处于LISTEN状态,等待客户端的连接请求。如果有连接请求,则立即作出响应。

         第一次握手:客户端A先创建传输控制块完成后,在打算建TCP连接时,向服务器端发出连接请求报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq=x。TCP规定,SYN报文段(即SYN=1)不携带数据,但要消耗掉一个序列号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态。此过程中,报文内容为:

         第二次握手:服务器收到请求报文段后,如果同意连接,则向发送连接请求方(客户端A)发送确认,即ACK(确认包)回应。在确认报文中把SYN位和ACK位都置为1,确认号为ack=x+1,同时自己也需选择一个初始序号seq=y。而且,这个确认报文段也不能携带数据,但要消耗一个序号。这时服务器端进程进入SYN-RCVD(同步收到)状态。此过程中,报文内容为:

         第三次握手:客户端A收到B的确认后,还要向B给出确认。确认报文段的ACK置为1,确认号ack=y+1,自己的序号seq=x+1。此时,ACK报文段可以携带数据,如果不携带数据则不用消耗序号。如果不携带数据,那么下一个数据报文段的序号仍然是seq=x+1。这时,TCP连接已建立,客户端A进入ESTABLISHED(以建立连接)状态。当服务器端B收到客户端A的确认后,也进入ESTABLISHED状态。此过程中,报文内容为:

         为什么A最后还要发送一次确认呢,即为什么不是两次握手?

         主要是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误,比如死锁。我们知道,三次握手需要完成两个重要的功能,既要双方做好发送数据的准备工作,也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。所谓“已失效的连接请求报文段”是这样产生的。正常情况下,A发出连接请求,但如果因为请求报文丢失而未收到确认。于是A再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接。A共发送了两个连接请求报文段,其中第一个丢失,第二个到达了B,没有“已失效的连接请求报文段”。异常情况下是,A发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达B。本来这是一个早已失效的报文段,但B收到此失效的连接请求报文段后,就误认为是A又发出的一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用报文握手,那么只要B发出确认,新的连接就建立了。由于现在A并没有发出建立连接请求,因此并不会理会B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立了,并一直在等待A发来数据。B的许多资源就这样被白白浪费了。采用三报文握手的办法,就可以有效地防止上述现象的发生。例如在上述的异常情况下,A不会向B的确认发出确认,B由于收不到A的确认,就知道A并没有要求建立连接。

         通俗举例来讲就是:

         A→B:你愿意嫁给我吗?

         B→A:我愿意。你愿意娶我吗?

         A→B:我愿意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值