TCP的三次握手和四次挥手

来源:互联网 发布:手机本地端口号 编辑:程序博客网 时间:2024/06/07 20:00

TCP是什么?

    TCP是TCP/IP体系中非常复杂的一个协议,关于TCP具体是什么,详细的介绍太复杂了,如果有兴趣了解,请参考《计算机网络》这本书,在这里就不详细说明了。简单来说,TCP(传输控制协议Transmission Control Protocol)是传输层的一个重要协议,也是因特网的正式标准,工作在传输层,提供面向连接的服务。

TCP报文段的首部格式

TCP是面向字节流的,但TCP传送的数据单元却是报文段。一个TCP报文段分为首部和数据两个部分,而TCP的全部功能都体现在它首部中各字段的作用。因此,只有弄清楚TCP首部各字段的作用才能掌握TCP的工作原理。下面就介绍一下各字段的含义。

源端口、目标端口:计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两个进程需要通信。源端口、目标端口是用16位表示的,可推算计算机的端口个数为2^16个

序列号(sequence number):表示本报文段所发送数据的第一个字节的编号。在TCP连接中所传送的字节流的每一个字节都会按顺序编号。由于序列号由32位表示,所以每2^32个字节,就会出现序列号回绕,再次从0 开始

确认号(acknowledgement number):表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。也就是告诉发送发:我希望你(指发送方)下次发送的数据的第一个字节数据的编号是这个确认号

数据偏移:表示TCP报文段的首部长度,共4位,由于TCP首部包含一个长度可变的选项部分,需要指定这个TCP报文段到底有多长。它指出TCP 报文段的数据起始处距离TCP 报文段的起始处有多远。该字段的单位是32位(即4个字节为计算单位),4位二进制最大表示15,所以数据偏移也就是TCP首部最大60字节

保留:占6位,保留为今后使用,但目前应置为0

下面有6个控制位说明本报文段的性质,它们的意义如下:

    URG:表示本报文段中发送的数据是否包含紧急数据。后面的紧急指针字段(urgent pointer)只有当URG=1时才有效

    ACK:表示是否前面的确认号字段是否有效。ACK=1,表示有效。只有当ACK=1时,前面的确认号字段才有效。TCP规定,连接建立后,    ACK必须为1,带ACK标志的TCP报文段称为确认报文段

    PSH:提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。如果为1,则表示对方应当立即把数据    提交给上层应用,而不是缓存起来,如果应用程序不将接收到的数据读走,就会一直停留在TCP接收缓冲区中

    RST:如果收到一个RST=1的报文,说明与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说    明上次发送给主机的数据有问题,主机拒绝响应,带RST标志的TCP报文段称为复位报文段

    SYN:在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方    同意建立连接。SYN=1,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中SYN才置为1,带SYN标志的TCP报    文段称为同步报文段

    FIN:表示通知对方本端要关闭连接了,标记数据是否发送完毕。如果FIN=1,即告诉对方:"我的数据已经发送完毕,你可以释放连接    了",带FIN标志的TCP报文段称为结束报文段

窗口大小:表示现在充许对方发送的数据量,也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量

校验和:提供额外的可靠性

紧急指针:标记紧急数据在数据字段中的位置

选项部分:长度可变,最长可达40字节

需要注意的是:不要将序列号ack控制位中的ACK弄混了

三次握手

所谓三次握手(Three-Way Handshake)即建立TCP连接。TCP是面向连接的,无论哪一方向另一方发生数据之前,都必须在双方建立一条连接。三次握手是为了建立可靠的连接服务。三次握手的目的是为了使每一方都知道对方的存在,双方协商一些参数(如最大窗口值、是否使用窗口扩大选项等),能够对传输实体资源(如缓存大小、连接表中的项目)进行分配。

TCP连接到的建立采用客户服务器方式。主动发起连接建立的应用进程叫做客户(client),而被动等待连接建立的应用进程叫做服务器(server)。

下面我们就来了解一下三次握手的具体过程,先来看图说话。

假定主机A运行的是TCP客户程序,而B运行TCP服务器程序。最初两端的TCP进程都处于CLOSED(关闭)状态。图中在主机下面的方框分别是TCP进程所处的状态。请注意,A主动打开连接,而B被动打开连接。

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

A的TCP客户进程也是首先创建传输控制模块TCB,然后向B发出连接请求报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq = x。TCP规定,SYN报文不能携带数据,但要消耗掉一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态,等待服务器进程的回应。

B收到连接请求报文段后,如同意进入连接,则向A发送确认。在确认报文段中应把SYN和ACK位都置1,确认号是ack = x + 1 ,同时也为自己选择一个初始序号seq = y。请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。

TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,确认号ack = y + 1,而自己的序号seq = x + 1.TCP的标准规定,ACK报文段可以携带数据。但如果不携带数据则不消耗序号,在这种情况下,下一个报文段的序号仍是 seq = x + 1。这时,TCP连接已经建立,A进入ESTABILSHED(已建立连接)状态。

当B收到A的确认后,也进入ESTABILSHED(已建立连接)状态。

上面给出的连接建立过程就叫做三次握手。完成三次握手后,客户端和服务器端就可以传送数据了。

为什么要三次握手?

这主要是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误

举例说明一下:

在上一个TCP连接中,A向B发送的连接请求SYN报文段滞留在网络中的某处。于是A超时重传,与B建立了TCP连接,交换了数据,最后也释放了TCP连接。

但滞留在网络中某处的陈旧的SYN报文段,现在突然传送到B了。如果不使用三次握手,那么B就以为A现在请求建立TCP连接,于是就分配资源,等待A传送数据。但A并没有想要建立TCP连接,也不会向B传送数据。B就白白等待着A发送数据。

如果使用三次握手,那么B在收到A发送的陈旧的SYN报文段后,就向A发送SYN报文段,选择自己的序号 seq = y,并确认收到A的SYN报文段,其确认号ack = x + 1。当A收到B的SYN报文段时,从确认号就可得知不应理睬这个SYN报文段(因为A现在并没有发送seq = x的SYN报文段)。这时,A发送复位报文段。在这个报文段中,RST=1,ACK=1,其确认号ack=y+1.我们注意到,虽然A拒绝了TCP连接的建立(发送了复位报文段),但对B发送的SYN报文段还是确认收到了。

B收到A的RST报文段后,就知道不能建立TCP连接,不会等待A发送数据了。

因此,三次握手防止服务器端因一直等待而浪费资源。

四次挥手

TCP的连接释放过程(即四次挥手)比较复杂,我们仍结合双方状态的改变来阐明连接释放的过程。还是先看图了解一下大致过程。

数据传输结束后,通信的双方都可释放连接。现在A和B都处于ESTABLISHED状态。A的应用进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。A把连接释放报文段首部的终止控制位FIN置1,其序号seq = u,它等于前面已传送过的数据的最后一个字节的序号+1.这时A进入FIN-WAIT-1(终止等待1)状态,等待B的确认。

B收到连接释放报文段后即发出确认,确认号为ack = u + 1,而这个报文段自己的序号是v,等于B前面已传送过的数据的最后一个字节的序号加1.然后B就进入CLOSED-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时的TCP连接处于半关闭状态。即A已经没有数据要发送了,但B若发送数据,A仍要接收。也就是说,从B到A这个方向的连接并未关闭,这个状态可能会持续一段时间。

A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。

若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。这时B发出的连接释放报文段必须使FIN=1.现假定B的序号为w(在半关闭状态B可能又发送了一些数据)。B还必须重复上次已发送过的确认号ack = u + 1.这时LAST-ACK(最后确认)状态,等待A的确认。

A在收到B的连接释放报文段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack = w + 1,而自己的序号是seq = u + 1。然后进入到TIME-WAIT(时间等待)状态。B收到ACK报文后,就可以进入CLOSED状态了。请注意,现在TCP连接还没有释放掉。必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,A才进入到CLOSED状态。当A撤销相应的传输控制块TCB后,就结束了这次的TCP连接。上述过程就是TCP的四次挥手。

为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当B收到A的FIN报文时,仅仅表示A不再发送数据了但是A还能接收数据,B也未必全部数据都发送给A了,这时的TCP连接处于半关闭状态。即A已经没有数据要发送了,但B若发送数据,A仍要接收。所以B可以立即close,也可以发送一些数据给A后,再发送FIN报文给对方来表示同意现在关闭连接,因此,B的ACK和FIN一般都会分开发送。因此需要四次挥手。

说了这么多,也该结束了。但是三次握手和四次挥手也仅仅是TCP协议的一小部分内容,关于TCP,还有很多内容需要学习。好了,结束!

 

 

 

 

 

 

原创粉丝点击