TCP建立连接三次握手和释放连接四次握手

    【尊重原创,转载请注明出处】http://blog.csdn.net/guyuealian/article/details/52535294

在谈及TCP建立连接和释放连接过程,先来简单认识一下TCP报文段首部格式的的几个名词(这里只是简单说明,具体请查看相关教程)

    序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
    确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。
    确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效
    同步SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。
    终止FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接
    PS:ACK、SYN和FIN这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq小写的单词表示序号。
一、TCP建立连接三次握手
(1)、三次握手的过程
   1)主机A向主机B发送TCP连接请求数据包,其中包含主机A的初始序列号seq(A)=x。(其中报文中同步标志位SYN=1,ACK=0,表示这是一个TCP连接请求数据报文;序号seq=x,表明传输数据时的第一个数据字节的序号是x);
   2)主机B收到请求后,会发回连接确认数据包。(其中确认报文段中,标识位SYN=1,ACK=1,表示这是一个TCP连接响应数据报文,并含主机B的初始序列号seq(B)=y,以及主机B对主机A初始序列号的确认号ack(B)=seq(A)+1=x+1)
   3)第三次,主机A收到主机B的确认报文后,还需作出确认,即发送一个序列号seq(A)=x+1;确认号为ack(A)=y+1的报文;
(2)为什么需要第三次握手?
     还要再发送一次确认是为了,防止已失效的连接请求报文段突然又传到了B,因而产生错误。
     已失效的报文段:正常情况下:A发出连接请求,但因为丢失了,故而不能收到B的确认。于是A重新发出请求,然后收到确认,建立连接,数据传输完毕后,释放连接,A发了2个,一个丢掉,一个到达,没有“已失效的报文段”
     但是,某种情况下,A的第一个在某个节点滞留了,延误到达,本来这是一个早已失效的报文段,但是在A发送第二个,并且得到B的回应,建立了连接以后,这个报文段竟然到达了,于是B就认为,A又发送了一个新的请求,于是发送确认报文段,同意建立连接,假若没有三次的握手,那么这个连接就建立起来了(有一个请求和一个回应),此时,A收到B的确认,但A知道自己并没有发送建立连接的请求,因为不会理睬B的这个确认,于是呢,A也不会发送任何数据,而B呢却以为新的连接建立了起来,一直等待A发送数据给自己,此时B的资源就被白白浪费了。但是采用三次握手的话,A就不发送确认,那么B由于收不到确认,也就知道并没有要求建立连接。
     简而言之:第三次握手,主机A发送一次确认是为了防止:如果客户端迟迟没有收到服务器返回的确认报文,这时他会放弃连接,重新启动一条连接请求;但问题是:服务器不知客户端没收到,所以他会收到两个连接请求,白白浪费了一条连接开销。
二、TCP释放连接四次握手
(1)四次握手过程
  假设主机A为客户端,主机B为服务器,其释放TCP连接的过程如下:
    1) 关闭客户端到服务器的连接:首先客户端A发送一个FIN,用来关闭客户到服务器的数据传送,然后等待服务器的确认。其中终止标志位FIN=1,序列号seq=u
   2) 服务器收到这个FIN,它发回一个ACK,确认号ack为收到的序号加1。
   3) 关闭服务器到客户端的连接:也是发送一个FIN给客户端。
   4) 客户段收到FIN后,并发回一个ACK报文确认,并将确认序号seq设置为收到序号加1。
     首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

     主机A发送FIN后,进入终止等待状态, 服务器B收到主机A连接释放报文段后,就立即给主机A发送确认,然后服务器B就进入close-wait状态,此时TCP服务器进程就通知高层应用进程,因而从A到B的连接就释放了。此时是“半关闭”状态。即A不可以发送给B,但是B可以发送给A。
  此时,若B没有数据报要发送给A了,其应用进程就通知TCP释放连接,然后发送给A连接释放报文段,并等待确认。A发送确认后,进入time-wait,注意,此时TCP连接还没有释放掉,然后经过时间等待计时器设置的2MSL后,A才进入到close状态。

(2)为什么要等待2MSL呢?
    MSL即Maximum Segment Lifetime,也就是最大报文生存时间,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。引用《TCP/IP详解》中的话:“它(MSL)是任何报文段被丢弃前在网络内的最长时间”。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。
    TCP的TIME_WAIT状态需要等待2MSL,当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。
    概括原因如下:
    ①、为了保证A发送的最后一个ACK报文段能够到达B。即最后这个确认报文段很有可能丢失,那么B会超时重传,然后A再一次确认,同时启动2MSL计时器,如此下去。如果没有等待时间,发送完确认报文段就立即释放连接的话,B就无法重传了(连接已被释放,任何数据都不能出传了),因而也就收不到确认,就无法按照步骤进入CLOSE状态,即必须收到确认才能close。
    ②、防止“已失效的连接请求报文段”出现在连接中。经过2MSL,那些在这个连接持续的时间内,产生的所有报文段就可以都从网络中消失。即在这个连接释放的过程中会有一些无效的报文段滞留在楼阁结点,但是呢,经过2MSL这些无效报文段就肯定可以发送到目的地,不会滞留在网络中。这样的话,在下一个连接中就不会出现上一个连接遗留下来的请求报文段了。
可以看出:B结束TCP连接的时间比A早一点,因为B收到确认就断开连接了,而A还得等待2MSL.
(3)为什么TCP释放连接需要四次?
      TCP建立连接要进行三次握手,而断开连接要进行四次。这是由于TCP的半关闭造成的。因为TCP连接是全双工的(即数据可在两个方向上同时传递)所以进行关闭时每个方向上都要单独进行关闭。这个单方向的关闭就叫半关闭。当一方完成它的数据发送任务,就发送一个FIN来向另一方通告将要终止这个方向的连接。
     注意:
     1)发送了FIN只是表示这端不能继续发送数据(应用层不能再调用send发送),但是还可以接收数据。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据,比如:如主机A收到主机B的FIN断开TCP连接请求,只是表示主机B已经发送完数据,主机A收到FIN后作出应答,并终止这个方向的数据传输,此时处于半关闭状态。但是主机A仍然可以发送数据的,只有当主机A发送完数据并发送FIN给主机B时,主机B才停止这个方向的数据传输,并关闭TCP连接。
     2)在很多时候,TCP连接的断开都会由TCP层自动进行,例如你CTRL+C终止你的程序,TCP连接依然会正常关闭,你可以写代码试试。

来源:http://blog.csdn.net/guyuealian/article/details/52535294

TCP建立连接三次握手和释放连接四次握手相关推荐

  1. 什么是三次握手、什么是四次握手

    在上一篇我们了解的TCP的报文格式和TCP连接管理机制:TCP初认识 今天来理解什么是三次握手,什么是四次挥手 图1 TCP连接管理 什么是三次握手 在网络数据传输中,传输层协议TCP(传输控制协议) ...

  2. Python--day41--事件和信号量之模拟连接数据库并在连接三次后抛出连接超时异常...

    #事件被创建的时候 #False状态 #wait()阻塞 #True状态 #wait() 非阻塞 #clear 设置状态为False #set 设置状态为True #数据库 --- 文件夹 #文件夹里 ...

  3. startupinfo为什么需要初始化_为什么 TCP 建立连接要三次握手

    为什么这么设计(Why's THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点.对具体实现造成的影响 ...

  4. mobaxterm为什么无法连接_为什么 TCP 建立连接需要三次握手

    为什么这么设计(Why's THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点.对具体实现造成的影响 ...

  5. TCP/IP 和 TCP/IP的 三/四次握手

    什么是TCP/IP 首先来说,TCP/IP协议是浏览器与服务器链接因特网的协议.浏览器使用TCP/IP协议进入服务器,服务器使用TCP/IP协议来发送HTML文件到浏览器. TCP/IP的作用 TCP ...

  6. TCP的三次挥手、四次握手

    三次握手 相关参数的描述: 消息类型 描述 SYN 同步序列编号 用来初始化和建立连接的 ACK 确认字符 帮助对方确认收到的SYN消息 SYN-ACK 本地的SYN消息和较早的ACK数据包 FIN ...

  7. 续篇( 一) TCP 为什么是三次握手,四次挥手?

    前两天在知乎上看到一个关于TCP协议的博文,没想到评论区竟然是华山论剑.高手论道,所以就悄悄的码住,吸取他们当中的精华,组合一下打狗棒法为我所用,哈哈~~~真的好贱,阿嚏,竟然有人骂我?废话不多说,上 ...

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

    http 和 https 请求相信大家都知道的,那么他们是怎样 connect 起来的?又是怎样 close 的呢?答案是先通过三次握手建立 connect 的,然后传输数据,最后通过四次握手 clo ...

  9. 三次握手过程和四次握手过程

    第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认:SYN:同步序列编号(Synchronize Sequence Numbers). 第二次 ...

最新文章

  1. 数据库收缩数据文件的尝试(二)(r11笔记第9天)
  2. Ubuntu修改IP地址和MAC地址
  3. Socket连接与HTTP连接
  4. stopstart按钮怎么用_烟雾报警器一直响吵人!怎么彻底给关掉?
  5. CentOs中怎样打开默认网卡并查看ip
  6. Eclipse中src/main/resources配置文件启动问题
  7. 阿里宣布取消的周报又死灰复燃?3分钟的高效报表才是最后出路
  8. Oracle修改SID(实例名)
  9. python中的命名空间指什么_python中命名空间
  10. SpringColoud学习笔记007---杂七杂八001--@Resource与@Autowired注解的区别
  11. CountDownLatch和CyclicBarrier的区别
  12. miui12怎么自定义开机动画_MIUI12相机特色功能须知,新增魔法分身与相机上滑启动更多模式...
  13. html图片随圆点下标轮播,基于JavaScript实现轮播图代码
  14. 吃一口肥肉之小程序牛刀小试(一)
  15. 2022年30本新年书单(要么旅行,要么读书,身体和灵魂总有一个在路上)
  16. 新年礼物送什么好?平价实用的蓝牙耳机推荐
  17. Android攻城狮组件篇—BroadcastReceiver
  18. 辅警是事业编制吗?辅警会纳入事业编制吗?
  19. Django发送HTML邮件
  20. Error connecting to the target: (Error -6305) PRSC module failed to write to to a register

热门文章

  1. 6.prometheus数据上报方式-pushgateway
  2. 2.关于QT中的Dialog(模态窗口),文件选择器,颜色选择器,字体选择器,消息提示窗口
  3. 你该认识这样的Linux_shell函数使用案例
  4. Scikit-learn 数据预处理之标准化StandardScaler
  5. Jenkins环境搭建总结
  6. unity3d___UGui中如何创建loading...进度条
  7. 云计算从“仰望星空”到“脚踏实地”
  8. CSS鼠标响应事件经过、移动、点击示例介绍
  9. linux下搭建cacti监控
  10. Oracle中SQL解析的流程