TCP三次握手及TCP四次挥手

目录

一.TCP简介

二.TCP数据包结构

三、TCP三次握手

四、TCP四次挥手



一.TCP简介

1、TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要释放连接。传输连接是用来传送TCP报文的。TCP的运输连接有三个过程,即建立连接、数据传输和连接释放。

2、客户端在收发数据前要使用 connect() 函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。

3、TCP建立连接时要传输三个数据包,俗称三次握手(Three-way Handshaking)

无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。

同时由于TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,TCP是全双工模式,所以需要四次挥手关闭连接。

  TCP连接建立过程中要解决以下三个问题:

  (1):要使每一方都能够确认对方的存在。

  (2):要允许双方协商一些参数

  (3):能够对运输实体资源进行分配

   TCP连接的建立采用客户机/服务器模式,主动发起连接建立的应用进程叫做客户机,而被动等待连接建立的应用进程叫做服务器。

二.TCP数据包结构

TCP协议规定了TCP传输数据的单元为TCP数据报。TCP数据报是对应用层进程交付数据的封装。

TCP数据报由两部分组成:TCP首部和TCP数据部分

  • TCP首部:包含许多控制和描述字段,是TCP全部功能的体现

  • TCP数据部分:对于应用层进程交付的数据,封装后的字节流序列

  • 应用层进程交付的数据被封装TCP报文,然后进行传输,TCP连接保证数据传输的可靠性,TCP报文传输的过程示意图:

  • TCP报文首部定义是TCP协议的精华所在,TCP复杂功能的实现,全部依靠了首部里各种控制字段。

        TCP端口号
    • TCP的连接是需要四个要素确定唯一一个连接:
      (源IP,源端口号)+ (目地IP,目的端口号)
      所以TCP首部预留了两个16位作为端口号的存储,而IP地址由上一层IP协议负责传递
      源端口号和目地端口各占16位两个字节,也就是端口的范围是2^16=65535
      另外1024以下是系统保留的,从1024-65535是用户使用的端口范围

      TCP报文的首部由20个字节固定字节和4n(n取[0~5]整数)个可变的选项字节组成,其中固定部分的各字段含义如下:

      源端口和目的端口:各占2个字节,分别写入通信双方进程端口号

      序号seq:占4个字节。在TCP连接中,传送的字节流中的每一个字节都是要按顺序编号[0~2^32-1],整个要传送的字节流的起始序号在必须连接建立时设置,序号字段值代表本报文段所发送的数据的第一个字节的序号

      确认号ack:占4个字节,是期望收到对方的下一个报文段的第一个数据字节的序号,即ack=N,就代表了到序号N-1为止的所有数据都被正确接收了。

      数据偏移:占4位,表示TCP报文的数据部分起始处距离TCP报文首部的起始处有多远,数据偏移值的单位是32位字(以4字节为计算单位),4位二进制能表示的值[0~15],这就意味着TCP首部最大长度为60字节,也就是选项部分的最大长度为40字节。

      保留位:占6位,保留为以后使用,目前置为0

      标志位:占6位,每个控制字段占1位,它们的标识和含义是:
      - 紧急URG:URG=1时,告诉系统此报文中有紧急数据,优先传送,与紧急指针配合使用
      - 确认ACK:当ACK=1时,确认号才有效,ACK=0时,确认号无效,TCP连接建立后,所有报文ACK必须都为1
      - 推送PSH:发送方把PSH置为1,接收方收到报文后会尽快交付,不用等缓存填满了再交付
      - 复位RST:当RST=1时,表明TCP连接出现了严重差错,必须释放连接,然后重新建立新运输连接。RST=1还可以用来拒接一个非法报文段或拒绝打开一个连接。
      - 同步SYN:在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段,对方若同意建立连接,则需要在响应报文中使SYN=1和ACK=1
      - 终止FIN:用来释放一个连接 。当FIN=1时,表明此报文段的发送方数据已经发送完毕,并且要求释放运输连接。

      窗口:占2字节,窗口值是[0~216-1]之间的整数。窗口值告诉了对方,从本报文段的确认号算起,允许对方发送的数据量。

      检验和:占2字节,用于接收方检验首部和数据部分是否在传输中有差错,类似我们下载文件时的Md5签名校验作用。

      紧急指针:占2字节,URG=1时才起作用,用于指明本报文段中的紧急数据的字节数,紧急数据结束后就是普通数据,所以紧急指针指出了紧急数据的末尾在报文中位置。

      选项:长度可变,最小0字节,最长达40字节。首部用来动态存储数据。
       

      三、TCP三次握手


    • (1)首先,客户机与服务器的TCP进程都处于CLOSED(关闭)状态,当要进行TCP连接时,客户机主动打开连接,服务器被动打开连接(这是因为服务请求总是由客户机向服务器发起,因为想要请求的资源都在服务器上,所以客户机想要获取资源就必须主动向服务器发起请求,而不能是等待服务器向自己(客户机)发起请求)。

      (2)然后,服务器的TCP进程先创建传输控制块TCB(传输控制块TCB存储了每一个连接中的重要信息,如:TCP连接表,指向发送和接收缓存的指针,指向重传队列的指针,当前的发送和接收序号,等等),此时,服务器就处于LISTEN(收听)状态。同样的,客户机也会首先创建一个传输控制块TCB发送给服务器。这样,准备工作就做好了。

      (3)现在就可以开始真正的三次握手了。首先,客户机先向服务器发送连接请求报文段,该报文段中将首部中的同步位SYN置为1(只有当SYN置为1时,才能表明客户机想要和服务器建立连接),并且随机选择一个初始序号x,注意此时的SYN数据报中并没有携带数据,但是仍旧要消耗掉一个序号(意思就是下次客户机发送数据的时候,序号为x+1),此时客户机进入到SYN-SENT(同步已发送)状态。

      (4)此时,服务器收到客户机的请求时,如果同意与该客户机进行连接,则需要向客户机发送确认报文。在发送报文中需要将SYN与ACK都置为1(当ACK置为1时,表明服务器同意与客户机进行连接;同时将SYN置为1,表明服务器想要和客户机建立连接),并且随机选择一个初始序号y,确认号为x+1(确认号表明服务器渴望收到的下一个报文段的第一个数据字节的序号,因为之前发送了x,所以下一个序号为x+1),注意此时的SYN数据报中并没有携带数据,但是也要消耗掉一个序号(同样的,也就是说服务器下次发送数据的时候,序号为y+1),此时TCP服务器进程进入到SYN-RCVD(同步收到)阶段。

      (5) TCP客户端收到服务器的确认后,还要再向服务器给出确认。确认报文段中ACK置为1,确认号为ack=y+1(因为之前服务器给客户机发送的序号为y,因此现在客户机向服务器发送的确认号为ack=y+1,意思是客户机渴望收到的下一个报文段的第一个数据字节为y+1)此时客户机的发送序号为x+1(这是因为刚才刚才客户机向服务器发送连接请求时消耗了序号x,因此此时的序号为x+1)注意:在进行第三次握手时,ACK报文段可以携带数据,也可以不携带数据,如果携带数据,则消耗一个序列,这样客户机下次发送报文段时的序号为x+2,如果不携带数据则不消耗序号,下次客户机发送报文段时的序号为x+1。这时TCP连接已经建立,客户机和服务器都进入ESTABLISHED(已建立连接)状态。

       

       

      为什么需要第三次通信 ?

       

      为什么client收到确认报文后,还要再发送一次确认报文给server呢?这主要是为了防止已失效的连接请求报文段突然又送到了Server端。

      假设现在TCP连接是两次握手机制,如下图server在收到client的连接请求,确认后就进入ESTAB-LISHED状态,会存在这样一种问题:

      client发送连接请求报文,由于网络原因,长时间阻塞在某个网络节点上了,于是client重传了一次请求连接报文,第二次请求报文正常达到server,连接正常建立,数据传输完毕后,释放连接。但是假设此时第一次发送的请求报文并没有丢失,而是延误一段时间才到达server,这本是已失效的连接请求报文段,但是server收到后,会以为是client重新发送的连接请求,于是向client发送确认报文后,进入ESTAB-LISHED状态,但是client并没有发出新建连接的请求,就会忽略server的确认报文,server却在一直等待client发送数据,导致server资源浪费严重。

       

      总结起来看,TCP三次握手过程就是client与server在相互确认各自发送和接收是否正常的过程:

      1、在第一次通信过程中,A向B发送信息之后,B收到信息后可以确认自己的收信能力和A的发信能力没有问题。

      2、在第二次通信中,B向A发送信息之后,A可以确认自己的发信能力和B的收信能力没有问题,但是B不知道自己的发信能力到底如何,所以就需要第三次通信。

      3、在第三次通信中,A向B发送信息之后,B就可以确认自己的发信能力没有问题。

      4、 小结:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
       

      四、TCP四次挥手

      建立连接非常重要,它是数据正确传输的前提;断开连接同样重要,它让计算机释放不再使用的资源。如果连接不能正常断开,不仅会造成数据传输错误,还会导致套接字不能关闭,持续占用资源,如果并发量高,服务器压力堪忧。

      四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。

      由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

       

      1.数据传输结束后,通信的双方都可以释放连接。此时,客户机和服务器都处于ESTABLISHED(已建立连接)状态。

        2.假设客户机请求完资源了,想要释放连接。首先,客户机的应用进程先向服务器发出连接释放报文段,该报文段中将首部的终止控制位FIN置为1(只有当FIN置为1时,才能表明客户机想要和服务器断开连接),并且序号为u(注意:此时的u不是随机产生的,而是之前客户机传送的数据的最后一个字节的序号加1)。此时客户机进入到FIN-WAIT-1(终止等待1)状态,等待服务器的确认。

        3.服务器收到连接释放报文后发出确认,在发送报文中将首部中的ACK置为1(ACK置为1,表面服务器同意与客户机释放连接),并且产生序号v(注意:此时的v不是随机产生的,而是之前服务器传送的数据的最后一个字节的序号加1),并且发出确认号为u+1(确认号表明服务器渴望收到的下一个报文段的第一个数据字节的序号,因为之前发送了u,所以下一个序号为u+1)。此时服务器就进入CLOSE-WAIT(关闭等待)状态,客户机进入FIN-WAIT-2状态。

              此时,从客户机到服务器这个方向的连接就被释放了,也就是说,客户机已经没有数据要向服务器发送了,但是如果服务器向客户机发送数据,客户机仍要接收数据。也就是说:从客户机到服务器的连接已经被释放了,但是从服务器到客户机的连接还没被释放。此时,TCP连接处于半关闭状态。

              4.如果服务器向客户机也没有要发送的数据的话,那么服务器的应用进程就可以向客户机发出连接释放报文段(注意此时还是服务器向客户机发送数据),该报文段中将首部的终止控制位FIN置为1(只有当FIN置为1时,才能表明客户机想要和服务器断开连接),ACK也置为1,并且序号为w(重点注意,此时的w不一定等于v+1。如果在客户机释放了连接之后,服务器向客户机仍旧发送了一部分数据,那么此时w不等于v+1,但是如果期间没有再发送数据,那么w就等于v+1。总而言之,这个w等于服务器上一次发送的数据的最后一个字节加1),并且发送确认号为u+1(确认号表明服务器渴望收到的下一个报文段的第一个数据字节的序号,因为之前收到了u,所以下一个序号为u+1)。此时服务器就进入了LAST-ACK(最后确认)状态。

             5.客户机收到服务器的连接释放报文后,必须对此报文进行确认。在该报文段中将ACK置为1,确认号为w+1(确认号表明客户端渴望收到的下一个报文段的第一个数据字节的序号,因为之前收到了w,所以下一个序号为w+1),产生序号为u+1(因为上一个发送的数据的序号为u)。此时服务器进入到TIME-WAIT(等待时间)状态。但是,此时TCP连接还没有被释放掉。必须经过2MSL后服务器才能进入到CLOSED状态。(注:MSL叫做最长报文段寿命,RFC建议为两分钟,也就是说,要经过四分钟才能进入到CLOSED状态)。

       

      为什么连接的时候是三次握手,关闭的时候却是四次握手?

       

      ①因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

      ②但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。

      ③只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值