TCP概述:

  它提供面向连接的服务,在传送数据之前必须先建立连接,数据传送完成后要释放连接。因此TCP是一种可靠的的运输服务,也正因为这样,不可避免的增加了许多额外的开销,比如确认,流量控制等。对应的应用层的协议主要有 SMTP,HTTP,FTP 等。TCP把连接作为最基本的对象,每一个TCP连接都有两个端点,这种端点就是套接字(socket),它的定义为端口号拼接到IP地址即构成了套接字。

TCP报文首部主要字段

  源端口和目的端口,各占2个字节,分别写入源端口和目的端口;

  序号seq,占4个字节,TCP连接中传送的字节流中的每个字节都按顺序编号。例如,一段报文的序号字段值是 301 ,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始;

  确认号ack,占4个字节,是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701;

  确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;

  同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;

  终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放;

TCP连接建立示意图:

  TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;

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

  TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。

  TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。

  当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。

那么问题是TCP客户端为什么最后还要发送一次确认呢?

  首先假设若使用的是两次握手建立连接的话,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

  那采用的是三次握手的话,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。主要就是防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。

TCP连接的释放:

  首先客户端进程发出连接释放报文并且停止发送数据。此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

  然后服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

  客户端收到服务器的确认请求后,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这期间还可以接受服务器发送的最后的数据)。

  服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

  客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

  服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤TCB后,就结束了这次的TCP连接。

为什么客户端最后还要等待2MSL?

  MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。

  1,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

  2,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

为什么关闭连接是四次挥手呢?

  关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

TCP为什么三次握手四次挥手的更多相关文章

  1. 在深谈TCP/IP三步握手&四步挥手原理及衍生问题—长文解剖IP

    如果对网络工程基础不牢,建议通读<细说OSI七层协议模型及OSI参考模型中的数据封装过程?> 下面就是TCP/IP(Transmission Control Protoco/Interne ...

  2. [na]TCP的三次握手四次挥手/SYN泛洪

    1.TCP报文格式 上图中有几个字段需要重点介绍下: (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记. (2)确认序号:Ack序号,占32位, ...

  3. TCP/IP三次握手四次挥手

    本文通过图来梳理TCP-IP协议相关知识.TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道.如图所示,给出了TCP通信过程的示意图. TCP 三次握手四次挥手 主要包括三部 ...

  4. TCP协议—三次握手四次挥手的原理<转>

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

  5. 救救孩子吧,到现在还搞不懂TCP的三次握手四次挥手

    本文在个人技术博客同步发布,详情可用力戳 亦可扫描屏幕右侧二维码关注个人公众号,公众号内有个人联系方式,等你来撩...   前几天发了一个朋友圈,发现暗恋已久的女生给我点了个赞,于是我当晚辗转反侧.彻 ...

  6. 通俗了解TCP/IP三次握手四次挥手

    前言: tcp/ip通信机制是计算机中很重要的一个知识点,不是一句两句就能解释清楚的,需要反复推敲其中的玄妙. 通俗理解: 但是为什么一定要进行三次握手来保证连接是双工的呢,一次不行么?两次不行么?我 ...

  7. TCP的三次握手四次挥手理解及面试题

    一.TCP概述 每一条TCP连接都有两个端点,这种端点我们叫作套接字(socket),它的定义为端口号拼接到IP地址即构成了套接字, 例如,若IP地址为192.0.0.1 而端口号为8000,那么得到 ...

  8. 详解 TCP的三次握手四次挥手

    本文转载来自https://blog.csdn.net/qzcsu/article/details/72861891 背景描述 通过上一篇中网络模型中的IP层的介绍,我们知道网络层,可以实现两个主机之 ...

  9. TCP/IP 三次握手-四次挥手

    TCP的建立需要三次握手,断开需要四次挥手. 首先三次握手: 首先,客户机向服务器发送请求报文,服务器回复ACK,并分配资源,而客户端接受到ACK后回复确认报文,并分配资源,此时三次握手完成. 四次挥 ...

  10. TCP的三次握手四次挥手

    一.三次握手 1.wireshark 抓包 2.TCP报文手部 注意标志位: 1).同步 SYN = 1 表示这是一个连接请求或连接接受报文. 2).只有当 ACK = 1 时确认号字段才有效.当 A ...

随机推荐

  1. 对FPM 模块进行参数优化!

    Nginx 的 PHP 解析功能实现如果是交由 FPM 处理的,为了提高 PHP 的处理速度,可对FPM 模块进行参数跳转.FPM 优化参数:pm 使用哪种方式启动 fpm 进程,可以说 static ...

  2. nyoj 24

    素数距离问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度.如果左右有等距离长度 ...

  3. windows网络编程-C语言实现简单的TCP协议聊天

    TCP/IP协议(面向连接协议)类似于打电话时,对方一定在手机附近并且此刻都在和对方进行通话.一定保证双方都在线,才能进行数据传输.UDP/IP协议(无连接协议)就像邮箱,不保证对方一定在等你邮件且对 ...

  4. Mapgis地图颜色配置(专题图配置)----对比Arcgis根据属性配置图斑颜色

    对于大多数arcgis用户来说,根据属性配置图斑颜色对于大家来说应该并不陌生.本文将就arcgis图斑颜色设置与mapgis做出比对,为大家提供更为绚丽的地图配色.    Arcgis颜色配置方案 右 ...

  5. 题解【[Ynoi2012]NOIP2015洋溢着希望】

    \[ \texttt{Preface} \] 第二道 Ynoi 的题,纪念一下. 这可能是我唯一可以自己做的 Ynoi 题了. \[ \texttt{Description} \] 维护一个长度为 \ ...

  6. Day11 - D - Race to 1 Again LightOJ - 1038

    设dp_i为所求答案,每次选择因数的概率相同,设i有x个因数,dp_i=sum(1/x*x_j)+1,(x_j表示第j个因数),那我们就预处理每个数的因数即可,T=10000,需要预处理出答案 #in ...

  7. vagrant up启动centos7时出现"rsync" could not be found on your PATH. Make sure that rsyncis properly ins

    (1)问题1:"rsync" could not be found on your PATH. Make sure that rsyncis properly ins 解决方法: ...

  8. python中的 dir()内置函数的作用以及使用方法

    dir() 内置函数的作用 python 内置方法有很多,无论是初学者还是精通python 的程序员都不能全部即住所有的方法,这时候 dir() 方法就非常有用了,使用 dir()函数可以查看对象内的 ...

  9. 解决HTML5(富文本内容)连续数字、字母不自动换行

    最近开发了一个与富文本相关的功能,大概描述一下:通过富文本编辑器添加的内容,通过input展示出来(这里用到了 Vue 的 v-html 指令). 也是巧合,编辑了一个只有数字组成的长文本,等到展示的 ...

  10. ubuntu---CUDA 安装注意点总结

    安装CUDA前的基础准备: 1.查看内核.gcc版本并记住. 最好 禁止内核更新,以防止以后工作中意外的系统更新使内核自动更新了,与驱动版本不兼容了.   2.禁用 nouveau驱动.   3.多下 ...