为什么三次握手,而不是两次或者四次五次?

2019/3/4更新:

      在阅读了很多技术博客后,发先大家对为什么三次握手不是两次众说纷纭;我觉得说的最好的是英文文章对TCP的解读。TCP和UDP的区别就是可靠与不可靠传输。

    为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护各自的一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。

在这过程中序号seq和确认号ack使用是核心。(详情请看下文)
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。

补充:

  第一次握手:A传给B包丢了的话,A会周期性重传,直到收到B的确认。

  第二次握手:B回传给A的序号+确认号包,A没有收到,B会周期性重传,直到收到A的确认。

    第三次握手:A发给B的包丢失

        A发完包后,单方面认为TCP是连接成功了,但是B只认为TCP是活跃状态。

情况1:假设双方没有数据要发送,B会重传,知道再收到A的确认。收到之后AB确认连接成功。

        情况2:A有数据发送,B收到A的数据和确认包,会认为TCP连接成功。并接收A数据。


往期:

首先要了解三次握手的具体过程:

为了建立客户端和服务端的数据连接进行TCP的三次交互

 

(1)第一次握手:建立连接时,client端发送给server端一个SYN包(标识位SYN=1和client的初始序列号seq=x,此时标识位ACK确认号=0,表示这是一个TCP连接请求数据报文),并进入SYN_SENT状态,等待server端确认。

(2)第二次握手:server端收到c端的发来的SYN包(即收到c端发来的连接请求),同时自己也发送一个SYN+ACK包(标识位SYN和ACK都置1,表示这是确认报文。server.seq=y,以及server对client初始序号的确认号server.ack=client.seq+1=x+1)。

(3)第三次握手:client收到server的SYN+ACK包,并向server发送一个序列号(client.seq=x+1),确认号为ack(client.ack=server.seq+1=y+1),此包发送完毕,客户端和服务器进入ESTAB_LISHED(TCP连接成功)状态,完成三次握手。

为什么是三次:如果只有两次(也就是客户端发送—服务端收到并发送—客户端收到)这个过程。假如服务端发出来的数据客户端没有收到呢(数据丢失的情况)? 客户端等待一段时间后,会重新建立连接,即重新发送连接请求。如果这个过程重复很多次,那么就会产生非常多的无效连接,占用大量资源,甚至导致服务器崩溃(也就是“SYN洪水攻击”现象)。

第三次握手,就是为了防止 因数据丢失或者数据传输延迟,导致客户端重启连接的现象。这也就防止了因服务器收到过的无效链接而占用大量资源。

为什么不是四次或五次?  对于TCP连接过程即C—>S—>C;如果是四次握手那么会产生和两次握手同样的无效化连接现象,而且比两次握手更浪费时间的资源。 那么你也就知道了为什么不五次握手,三次五次七次都可以做到确认并连接成功,为什么不用最少的时间和资源呢?

为什么四次挥手?

 

第一次挥手:首先,client端发送一个FIN (用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接),用来关闭client端到server的数据传送,然后等待server端的确认。其中终止标志位FIN=1,序列号seq=u。

第二次挥手:当server收到这个FIN后,它会发送一个ACK,确认号ack(ack=client.seq+1=u+1),序列号seq=v,确认已经收到了client端的终止请求。

第三次挥手:关闭服务器到客户端的连接,发送一个FIN给客户端,FIN=1,更新的序列号seq=w,确认号ack=u+1(和第二次挥手相同)。

第四次挥手:当client收到FIN后,并发回一个ACK报文确认已经收到,其中seq=u+1,ack=server.seq+1。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

总结全过程:客户端第一次发送FIN后,进入终止等待状态,服务器收到客户端连接释放报文段后,就立即给客户端发送确认,服务器就进入CLOSE_WAIT状态,此时TCP服务器进程就通知高层应用进程,因而从客户端到服务器的连接就释放了。此时是“半关闭状态”,即客户端不可以发送给服务器,服务器可以发送给客户端。此时,如果服务器没有数据报发送给客户端,其应用程序就通知TCP释放连接,然后发送给客户端连接释放数据报,并等待确认。客户端发送确认后,进入TIME_WAIT状态,但是此时TCP连接还没有释放,然后经过等待计时器设置的2MSL后,才进入到CLOSED状态。

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

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。(原文:https://blog.csdn.net/qq_38950316/article/details/81087809)

为什么最后会有客户端等待2MSL时间?

MSL是最大报文生存时间。为了保证客户端发送的最后一个ACK报文段能够到达服务器。即最后一个确认报文可能丢失,服务器会超时重传,然后服务器发送FIN请求关闭连接,客户端发送ACK确认。一个来回是两个报文生命周期。

如果没有等待时间,发送完确认报文段就立即释放连接的话,服务器就无法重传,因此也就收不到确认,就无法按步骤进入CLOSED状态。

并且可以防止已经失效的连接请求报文出现在连接中。经过2MSL,在这个连续持续的时间内,产生的所有报文段就可以都从网络消失。

总结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. iOS Core Data 数据库的加密(待研究)

    https://github.com/project-imas/encrypted-core-data 使用起来很方便,底层还是使用了SQLCipher,有时间要研究一下! 数据库的密码不能用固定字符 ...

  2. yum报错:Error: Multilib version problems found. This often means that the root

    使用yum安装一些依赖库报错: yum -y install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel 错误信 ...

  3. PID控制器开发笔记之十一:专家PID控制器的实现

    前面我们讨论了经典的数字PID控制算法及其常见的改进与补偿算法,基本已经覆盖了无模型和简单模型PID控制经典算法的大部.再接下来的我们将讨论智能PID控制,智能PID控制不同于常规意义下的智能控制,是 ...

  4. Modbus库开发笔记之九:利用协议栈开发Modbus TCP Server应用

    前面我们已经完成了Modbus协议栈的开发,但这不是我们的目的.我们开发它的目的当然是要使用它来解决我们的实际问题.接下来我们就使用刚开发的Modbus协议栈开发一个Modbus TCP Server ...

  5. Confluence 6 配置推荐更新邮件通知默认的初始化设置

    Confluence 为订阅者发送常规邮件报告,这个邮件报告中包含有用户具有查看权限的空间的最新的内容.这个被称为 推荐更新(Recommended Updates)通知. 如果你具有 Conflue ...

  6. bat如何创建多级文件夹(在android设备中)

    在android设备中要创建多个或者多级文件夹时,手动去创建费时费力(有点傻),一个bat文件就能很好的实现这个功能. 1.首先创建同级多个文件夹且在该文件夹下生成一个文件 @echo off ech ...

  7. 扇形多级菜单可配置Demo

    预览效果 领导是想把这个做成复选框,所以做成了可以多选的... Demo下载:https://github.com/zhangzn3/arc-menu

  8. ActiveMQ消息的发送原理

    持久化消息和非持久化消息的发送策略:消息同步发送和异步发送 ActiveMQ支持同步.异步两种发送模式将消息发送到broker上.同步发送过程中,发送者发送一条消息会阻塞直到broker反馈一个确认消 ...

  9. LeetCode(122):卖股票的最佳时机 II

    Easy! 题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参 ...

  10. cf919D 线性dp+拓扑排序

    /* 给定一张有向图,图上每个结点都有一个字符,现在要求出一条路径,要使路径上某字符出现的次数最多 如果有环,输出-1即可 拓扑排序+dp dp[i][26]表示排序到结点i时26个字符出现的次数 在 ...