1. 三次握手

  1. TCP为什么相较于UDP是可靠连接?

    可靠连接是指,待通信的两个实体,能够满足通信数据包的有序性、完整性以及可靠性。对于UDP来说, 它的连接过程不需要握手,忽略丢失的数据包,并且不需要维持通信双方在线(即服务器端不需要维持巨大的并发连接)。而TCP在传递数据之前,会经历三次握手来确保通信的两个实体均处于ESTANLISHED状态, 另外还采用校验和、序列号、确认应答、超时重传、拥塞控制、拥塞避免等控制方法,以此来确保数据的可靠传输。

  2. 三次握手的本质

    三次握手的本质在于确保通信双方收到彼此请求/接收通信的确认消息

    这里我们以电话拨号到通话为例,假设A给B通电话,那么其过程如下:

    A. 拨号,(请求与B通话)

    B. 拿起电话并接听,“喂!您哪位?”,(希望确认A的身份) 

    A. 收到对方询问身份, 并回复“我是A啊”,  (回传身份确认消息)

    B. 收到回复,并确认了A的身份, 开始尬聊

  3. 三次握手的过程

    

    第一次握手:客户端主动请求建立连接。 客户端发送连接请求报文段, 将SYN首部标志位置为1, Seq(Sequence Number)为X(由操作系统动态随机选取一个32位长(8字节)的系列号。随后客户端进入SYN_SEND状态,并等待服务器端的确认。

    第二次握手:服务器收到客户端SYN请求,并发送被动连接请求。服务器收到第一次握手过程中接收的SYN,需要向客户端发送一个确认号ACK(收到的Seq序列号长度自增1),此外,还需将被动请求连接请求发送给客户端,及SYN=1, 最后再从操作系统随机分配一个8字节长度的序列号用于填充Seq,将以上信息发送给客户端之后,服务器端便进入SYN_RECV状态。等待来自客户端的响应请求确认。

    第三次握手:客户端收到服务器的被动连接请求,并发送确认号。客户端收到SYN&Seq&ACK之后,发送确认请求,ACK为接收的Seq序列号自增1,Seq为接收的ACK确认号。至此TCP便完成了三次握手。

    

    - URG: 此标志表示TCP包的紧急指针域(有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据。
    - ACK: 此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中。有两个取值: 0和1,为1的时候表示应答域有效,反之为0。
    - PSH: 这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队。
    - RST: 这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包。
    - SYN: 表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0。连接被响应的时候,SYN=1,ACK=1。这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口。但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手。
    - FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
 

  4. 为什么是3次握手,而不是2次或者4次?

在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是
“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。
在另一部经典的《计算机网络》一书中讲“三次握手”的目的是为了解决“网络中存在延迟的重复分组”的问题。
这两种不同的表述其实阐明的是同一个问题。
谢希仁版《计算机网络》中的例子是这样的,
“已失效的连接请求报文段”的产生在这样一种情况下:
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,
以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。
但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。
于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。
由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。
但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
采用“三次握手”的办法可以防止上述现象发生。
例如刚才那种情况,client不会向server的确认发出确认。
server由于收不到确认,就知道client并没有要求建立连接。”

  我们也可以假想一下,如果是两次握手,那么客户端向服务端发送请求连接SYN这是第一次握手服务器向客户端发送确认收到SYN的请求这是第二次握手,此时问题就来了,结果就是只要服务器发送一个确认报文给客户端,那么就代表连接建立了,但是网络信道是不可靠的,很容易碰到高时延的情况发生,假设一个来自客户端本就失效的连接报文(SYN)经过很长时间到达了服务器端(客户端早已断开连接),此时服务器按照流程返回一个确认号,便进入了ESTABLISHED状态,这样一来服务器状态与客户端状态便不一致了,假设有多个这样的情况发生,操作系统内存很容易崩溃。

  说完了两次,那么四次呢? 四次握手其实是可以的。其与三次握手的相同之处在于,必须收到彼此的对应请求报文的确认号才进入ESTABLISHED状态。但是,四次握手不必要,他将第二次握手的ACK与SYN分两次进行发送了,其结果就是连接速度效率低。

  因此采用建立TCP连接三次握手是必要的。

2.四次挥手

  1. 四次挥手过程

  

    四次挥手不存在Client及Server的说法, 因为客户端及服务器都能够主动关闭连接。

    第一次挥手:主动方主动提出关闭连接。当主动方发送断开连接请求(FIN=1, Seq=X)给被动方之后, 主动方由ESTABLISHED状态转为FIN-WAIT-1状态等待来自服务器的确认消息。

    第二次挥手:被动方收到来自主动方的FIN请求,被动方关闭应用层的应用程序,响应一个确认报文(ACK=x+1, Seq=y),并进入CLOSE-WAIT状态。

    第三次挥手:被动方发送被动断开连接请求给主动方。但此时可能出现应用程序有些TCP消息已经存在于被动方的发送队列中,这部分数据仍能参与传送,所以等到数据发送完毕之后,被动方才发送被动断开连接请求(FIN=1, Seq=m,ACK=x+1), 并等待主动方确认,进入LAST-ACK状态。

    第四次挥手:主动方接收到被动方发送来的被动断开连接请求, 主动方发送确认(ACK=m+1, seq=x+1),注意第四次挥手的Seq字段为第二次挥手的ACK字段的值。

  2. 为什么连接的时候是3次,握手就是四次呢?

    这是因为在第二次挥手的时候, 被动方接收到来自主动方的主动断开连接请求,随即进入CLOSE-WAIT状态,为什么会存在这一个状态呢?是因为TCP通信过程中,其发送窗口仍存在该应用程序待发送的数据报文,必须等待这些报文全部发送完毕之后,才能够发送被动断开连接请求。所以将FIN及ACK分两次进行。

  

  3. 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

    (补充:2MSL为最大报文段生存时间,代表发送到接收的最大时间)网络信道是不可靠的,随时都有可能发生请求超时的情况,假设第四次握手时,主动方发送的ACK确认报文丢失或超时,那么被动方由于不能收到该确认报文, 它就会又发送一个第三次握手的被动断开连接报文(FIN=1........),此时在TIME_WAIT状态下,主动方收到被动方的FIN请求,便开始重传ACK报文给被动方。因此,TIME-WAIT的意义就在于出现确认报文丢包时,能够重传确认报文。

    

  

浅析TCP三次握手及四次挥手的更多相关文章

  1. 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    .引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方 ...

  2. [转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手   http://www.52im.net/thread-1729-1-1.html     1.引言 网络编程中TCP协议的三次握手和 ...

  3. TCP三次握手及四次挥手详细图解

    TCP三次握手及四次挥手详细图解 Andrew Huangbluedrum@163.com    相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不 ...

  4. 用wireshark抓包分析TCP三次握手、四次挥手以及TCP实现可靠传输的机制

    关于TCP三次握手和四次挥手大家都在<计算机网络>课程里学过,还记得当时高超老师耐心地讲解.大学里我遇到的最好的老师大概就是这位了,虽然他只给我讲过<java程序设计>和< ...

  5. 应聘复习基础笔记1:网络编程之TCP与UDP的优缺点,TCP三次握手、四次挥手、传输窗口控制、存在问题

    重要性:必考 一.TCP与UDP的优缺点 ①TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供 ...

  6. 【HTTP协议】---TCP三次握手和四次挥手

    TCP三次握手和四次挥手 首先我们知道HTTP协议通常承载于TCP协议之上,HTTPS承载于TLS或SSL协议层之上 通过上面这张图我们能够知道.     在Http工作之前,Web浏览器通过网络和W ...

  7. 网络通信 --> TCP三次握手和四次挥手

    TCP三次握手和四次挥手 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 一.TCP报文格式 如下图: (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发 ...

  8. TCP‘三次握手’和‘四次挥手’(通俗易懂)

      概述 我们都知道 TCP 是 可靠的数据传输协议,UDP是不可靠传输,那么TCP它是怎么保证可靠传输的呢?那我们就不得不提 TCP 的三次握手和四次挥手. 三次握手 下图为三次握手的流程图 下面通 ...

  9. 【转】TCP三次握手和四次挥手全过程及为什么要三次握手解答

    TCP三次握手和四次挥手的全过程   TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种表示: SYN(synchronous建立连接) ...

随机推荐

  1. fastDFS的入门程序

    导入jar包 <dependency> <groupId>cn.bestwu</groupId> <artifactId>fastdfs-client- ...

  2. Qt 添加程序图标和系统托盘图标

    添加程序图标 第一种方法: 1.创建程序的时候,选择添加默认图标 2.替换程序目录下的ico文件,编译生成即可. 第二种方法: 比较适合一开始没有添加程序图标的情况 1.项目右键-->添加--& ...

  3. Step by Step to create orders by consuming SAP Commerce Cloud Restful API

    Recently Jerry is working on an integration project about creating orders in Wechat platform by cons ...

  4. 【微信小程序】——wxss引用外部CSS文件及iconfont,图文教程

    小程序引入外部文件的方式是:@import “/.wxss”; 小程序的wxss文件font-face的url不接受http地址作为参数,可以接受base64,因此可以先将字体文件下载后,转换为bas ...

  5. 六、MySQL系列之数据备份(六)

    本篇主要介绍用户授权.以及数据备份等知识: 一.用户授权 首先我们需要知道的是: 所有的用户及权限信息都存储在mysql数据库下的user表中,故我们可以通过查看user表的记录来查看用户权限信息,当 ...

  6. python面试总结2(函数常考题和异常处理)

    python函数常考题 可变类型为参数 不能类型为参数 python如何传递参数 传递值还是引用呢?都不是.唯一支持的参数传递是共享穿参 Call by Object(Call by Object R ...

  7. kubectl 命令自动补全

    kubectl 命令自动补全 在linux上 # yum install -y bash-completion # source /usr/share/bash-completion/bash_com ...

  8. 微信小程序分享朋友圈 长海报 canvas 动态高度计算

    业务场景 在微信中 小程序无法分享到朋友圈,目前大部分的解决方案都是,canvas动态绘制 生成图片后,保存到用户相册,用户进行分享照片到朋友圈,朋友圈打开图片后识别二维码进入小程序,达到分享目的 g ...

  9. docker 运行ELK

    docker network create somenetwork docker run -d --name elasticsearch --net somenetwork -p 9200:9200 ...

  10. linux系统编程综合练习-实现一个小型的shell程序(三)

    上节中已经实现了对普通命令的解析,包括输入重定向,输出重定向,管道,后台作业,这次就来执行已经解析好的命令,对应的函数为:execute_command(),首先对带有管道的命令进行执行: 比如:&q ...