三次握手(建立连接)

  1. 首先,服务器进程(B)先创建传控制块TCB(用来存储连接信息,如连接表,发送和接收序号等),准备接收客户进程(A)的请求。然后服务器进程处于LISTEN(收听)状态,等待客户的连接请求。客户进程(A)同样也是首先创建传输控制块TCB,然后向服务器B发出连接请求报文。报文首部的同步位SYN=1,同时选择一个初始的序号seq=x(TCP规定,SYN=1的报文不能携带数据,但是要消耗掉一个序号),这时TCP客户进程进入SYN-SENT(同步已发送)状态。
  2. 服务器进程(B)收到连接请求后,如同意连接,则向A发送确认。在确认报文中SYN位和ACK位都为1,确认号ack=x+1,同时自己选择一个初始序号seq=y。(这个报文也不能携带数据,同样要消耗一个序号),这是服务器进程(B)进入SYN-RCVD(同步收到)状态。
  3. 客户进程(A)收到B的确认后,还要向B发送确认。确认报文的ACK=1,确认号为ack=y+1,自己的序号为seq=x+1,(TCP规定,ACK报文可以携带数据,如果不携带则不消耗序号,这样的话,下一个数据报文段的序号仍是seq=x+1),这时,TCP连接已建立,A进入ESTABLISHED状态,当B收到A的确认后,同样也进入ESTABLISHED状态。

问题:为什么A还要发送一次确认呢?(为什么是三次握手,不是两次)

答:主要是为了防止已经失效的连接请求报文突然又传送到B,因而产生错误。例如,当A发送连接请求,但是因为网络延迟等原因,在某个网络节点滞留,迟迟未到达B,所以A未收到B的确认,这时候A重新发送了一次请求报文,这次正常建立连接。数据传输完毕后,正常释放连接。突然这时候B收到了A第一次发送的请求报文,以为A又要重新建立连接。这时发送了确认报文,同意建立连接。如果这时不采用三次握手,那么只要B发送确认,新的连接就建立了。由于A没有发出建立连接的请求,因此不会搭理B,也不会向B发送数据,而B以为新的连接建立了,一直在等待A发来数据,B的许多资源就这样白白浪费了。这种情况下,如果采用三次握手,A不会向B发送确认,B由于收不到确认,就知道A没有建立连接。

四次握手(释放连接)

  1. 双方传输结束后,通信双方都可以释放连接。现在A和B都处于ESTABLISHED状态。A进程向B发送连接释放报文,并停止发送数据。报文的首部终止控制位FIN=1,序号为u(序号u等于前面传送过的数据的最后一个字节的序号加1),这是A进入FIN-WAIT-1(终止等待1)状态,等待B的确认。
  2. B收到连接释放报文后即发出确认ACK=1,确认号为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发出的连接释放报文段。
  3. 如果B没有数据向A发送了,其应用进程就通知TCP释放连接。这是B发送连接释放报文必须使FIN=1,假定B的序号为w,(因为在半关闭状态B可能又发送了一些数据),B必须重复上次已发送的确认号ack=u+1,确认位ACK=1。这时B进入LAST-ACK(最后确认)状态,等待A的确认。
  4. A收到B的连接释放报文后,必须对此发出确认。在确认报文中把ACK置为1,确认号为ack=w+1,而自己的序号是seq=u+1,然后进入TIME-WAIT(时间等待)状态。请注意,现在TCP连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,A才进入CLOSED状态。(MSL-Maximum Segment Lifetime叫做最长报文段寿命,建议为2分钟),因此A进入到TIME-WAIT状态后,要经过4分钟才能进入到CLOSED状态,才能开始建立下一个新的连接。

问题:为什么A在TIME-WAIT状态必须等待2MSL的时间呢?

答:为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,因此处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后A和B都正常进入到CLOSED状态。如果A不等待一段时间,而是立即释放连接,那么就无法收到B的重传FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常的步骤进入CLOSED状态。另一个原因是,防止已失效的连接请求报文段出现在本连接中,A在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使得下一个新的连接中不会出现这种旧的连接请求报文段。

TCP的三次握手和四次握手的更多相关文章

  1. TCP连接和连接释放(TCP的三次挥手和四次握手)

    TCP的运输连接管理 TCP是面向连接的协议.运输连接是用来传送TCP报文的.TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程.因此,运输连接就有三个阶段,即:连接建立.数据传送和连接 ...

  2. TCP/IP协议三次握手与四次握手流程解析

    原文链接地址:http://www.2cto.com/net/201310/251896.html TCP/IP协议三次握手与四次握手流程解析 TCP/IP协议的详细信息参看<TCP/IP协议详 ...

  3. TCP/IP协议三次握手与四次握手流程解析(转载及总结)

    原文地址:http://www.2cto.com/net/201310/251896.html,转载请注明出处: TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式  TCP/IP协议的详 ...

  4. TCP/IP协议三次握手与四次握手

    TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式  TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷本.下面是TCP报文格式图:图1 TCP报文格式  上图中有几个 ...

  5. 抓包分析TCP的三次握手和四次握手

    问题描写叙述: 在上一篇<怎样对Android设备进行抓包>中提到了,server的开发者须要我bug重现然后提供抓包给他们分析.所以抓好包自己也试着分析了一下.发现里面全是一些TCP协议 ...

  6. 三次握手、四次握手、backlog

    TCP:三次握手.四次握手.backlog及其他   TCP是什么 首先看一下OSI七层模型: 然后数据从应用层发下来,会在每一层都加上头部信息进行封装,然后再发送到数据接收端,这个基本的流程中每个数 ...

  7. tcp三次握手和四次握手

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

  8. TCP/IP 三次握手和四次握手

    三次握手建立连接: 第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己 ...

  9. TCP/IP具体解释--三次握手和四次握手 Dos攻击

    TCP连接的状态图 TCP建立连接的三次握手过程,以及关闭连接的四次握手过程 贴一个telnet建立连接,断开连接的使用wireshark捕获的packet截图. 1.建立连接协议(三次握手) (1) ...

  10. TCP:三次握手、四次握手、backlog及其他

    TCP是什么 首先看一下OSI七层模型: 然后数据从应用层发下来,会在每一层都加上头部信息进行封装,然后再发送到数据接收端,这个基本的流程中每个数据都会经过数据的封装和解封的过程,流程如下图所示: 在 ...

随机推荐

  1. 转Keil 中使用 STM32F4xx 硬件浮点单元

    Keil 中使用 STM32F4xx 硬件浮点单元一.前言有工程师反应说 Keil 下无法使用 STM32F4xx 硬件浮点单元, 导致当运算浮点时运算时间过长,还有 一些人反应不知如何使用芯片芯片内 ...

  2. sql server 2008r2 备份到局势网共享硬盘

    首先,如果没有启用xp_cmdshell,请执行以下启用: ; ; RECONFIGURE; 1.创建映射: exec master..xp_cmdshell 'net use \\192.168.9 ...

  3. Zeppelin的入门使用系列之使用Zeppelin来创建临时表UserTable(三)

    不多说,直接上干货! 前期博客 Zeppelin的入门使用系列之使用Zeppelin运行shell命令(二) 我们必须要先使用Spark 语句创建临时表UserTable,后续才能使用Spark SQ ...

  4. ios获取数据之encodeURI 和 decodeURI

    在APP开发过程中,免不了要进行ios的数据处理,在ios传递数据的过程中,会出现JSON数据获取不到的情况,这时候就轮到encodeURI 和 decodeURI出马了. 1.encodeURI,d ...

  5. Cocos2d-x v3.1 初识(一)

    Cocos2d-x v3.1 初识(一) Cocos2d-x从以前苹果平台上的Cocos2d发展而来,版本已经更新到了3.1.1.作为一个跨平台的游戏开发引擎,现在已经被上百个国家在使用,这也是国人的 ...

  6. 电话号码 马赛克*号 string类扩展

    /// <summary> /// 字符串马赛克 /// </summary> /// <param name="source"></pa ...

  7. PHP的加解密:如何安装ioncube扩展?

    一.下载loader-wizard.php(支持php5.3.php5.4.php5.5.php5.6版本) ioncube提供了一个安装的向导程序,可以非常方便的帮助检测php的运行环境,自动给出提 ...

  8. allure使用简介

    #安装依赖包pip install requests_toolbeltpip install pyyamlpip install pytest-allure-adaptor #安装allure2 说明 ...

  9. Python+selenium之fixtures

    fixtures即可以表示测试用例的开始和结束,也可以表示测试类和测试模块的开始和结束. import unittest def setUpModule(): print("test mod ...

  10. github上fork原项目,如何将本地仓库代码更新到最新版本?

    场景: 在github上fork原项目,项目组成员发起pull request提交了代码,这时自己在本地仓库该如何更新到最新代码? 操作方法如下: 方法一.从github上进行操作然后更新 登录自己的 ...