由浅入深理解TCP三次握手,为什么不是三次而不是二次或者四次呢?

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 由浅入深理解TCP三次握手,为什么不是三次而不是二次或者四次呢?

1 预备知识

1.1 IP协议

IP协议是无连接的通信协议,他不会占用两个正在通信的计算机之间的通信线路,这样IP就降低了对网络线路的需求,每条线可以同时满足许多不同的计算机之间的通信需要。通过IP、消息或者其他数据会被分割为较小的独立的包,并通过因特网在计算机之间传送。IP负责将每个包路由至他的目的地,但IP协议没有确认数据包是否按顺序发送或者包是否损坏,所以IP数据包是不可靠的,需要由他的上层协议作出控制。


1.2 TCP协议(传输控制协议)

面向连接的、可靠地、基于字字节流的传输层通信协议


将应用层的数据流分割成报文段并发送给目标节点的TCP层


数据包都有序号,对方收到则发送ACK确认,未收到则重传


使用校验和检验数据在传输过程中是否有误


1.3 TCP报文头

TCP和UDP均不包含IP信息,但是包含了源端口和目的端口(端口属于传输层范畴)


两个进程在计算机内部进行通信可以有管道、内存共享、信号量、消息队列等方法。


通信前提:唯一的标识一个进程。本地通信中PID(进程标识符/进程号)来唯一标识进程,PID仅在本地唯一,两个进程在不同的计算机则可能重复。


IP+协议+端口号唯一标识网络中的一个进程。套接字Socket模式


20201027170338226.png


1.4 TCP Flags:TCP控制位,由8个标志位来组成,每个标志位表示一个控制功能。

URG:紧急指针标志 1紧急指针有效;0忽略紧急指针


ACK:确认序号标志 1确认号有效;0报文中不含确认信息,忽略确认号字段


PSH:push标志 1是带有push标志的数据,指示接收方在接收到该报文段以后应尽快将该报文段交给应用程序,而不是在缓冲区排队


RST:重置连接标志 用于重置由于主机崩溃或者其他原因而出现错误的链接,或者用于拒绝非法的报文段和拒绝连接请求


SYN:同步序号 同于建立连接过程,在连接请求中SYN=1和ACK=0表示该数据段没有使用捎带的确认域,连接应答捎带确认则SYN=1和ACK=1


FIN:finish标志 用于释放连接,1表示发送方没有数据发送,即关闭本方数据流


2 三次握手和四次挥手

2.1 三次握手

20201027170501803.png


现实场景简单理解:(自己是客户端,朋友是服务器)


我:在吗兄弟,出去玩?


兄弟:在的,你确定?


我:没问题


这三次握手然后成功建立交互出去玩!


2.2 四次挥手

2020102717052695.png


现实场景简单理解:(自己是客户端,朋友是服务器)


我:再见了兄弟,我要回家了。


兄弟:你等等我收拾完咱们的东西再走啊!


兄弟:你确定不玩会儿?


我:不了,老婆叫我回家吃饭。


然后四次挥手结束。


3 备战面试面试题要说出这些

TCP三次握手和四次握手的工作流程是什么?为什么不是五次握手或者两次握手?


3.1 面试官心里分析

这个问题相当经典,大家可别以为就是考察应届生的,实际上在普通社招java面试中,一些大公司,很喜欢考察这个问题,尤其是后面第二个追加问题,让你聊聊为啥必须是三次握手,而不是两次呢?


3.2 tcp三次握手过程

20201027172014599.png


详情理解:


在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。


  1. 第一次握手:建立连接时,客户端发送同步序号SYN包(seq=j seq初始序号任意正整数)到服务器,并进入SYN_SEND状态,等待服务器确认;不能消耗

  2. 第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=j+1) ,同时自己也发送一个SYN包(seq=k) , 即SYN+ACK包,此时服务器进入SYN_RECV状态;

  3. 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,如果携带数据seq+1,没有就不消耗客户端和服务器进入ESTABLISHED状态,完成三次握手。


解析:seq是序列号,这是为了连接以后传送数据用的,ack是对收到的数据包的确认,值是等待接收的数据包的序列号。  在第一次消息发送中,A随机选取一个序列号作为自己的初始序号发送给B;第二次消息B使用ack对A的数据包进行确认,因为已经收到了序列号为x的数据包,准备接收序列号为x+1的包,所以ack=x+1,同时B告诉A自己的初始序列号,就是seq=y;第三条消息A告诉B收到了B的确认消息并准备建立连接,A自己此条消息的序列号是x+1,所以seq=x+1,而ack=y+1是表示A正准备接收B序列号为y+1的数据包。


seq是数据包本身的序列号;ack是期望对方继续发送的那个数据包的序列号。  



3.3 为啥不是2次或者4次握手呢?

da535c4da4db4f089cd3db301f000639.png


现实场景简单理解:(自己是客户端,朋友是服务器)


我:在吗兄弟出去玩啊?(现在手机网不好卡主了。)


我(换个设备打电话):在吗兄弟出去玩啊?


兄弟:好,老地方见。------此时开始收拾东西准备出发


现在建立连接去玩。


过了几天...


我:【在吗兄弟出去玩啊?(现在手机网不好卡主了。)】这条信息wifi好了,又发出去了


兄弟:好,老地方见。------此时开始收拾东西准备出发


但是此时我并不知道要去玩,就让兄弟一直等着浪费资源,浪费时间!


假设两次握手就ok了,要是客户端第一次握手过去,结果卡在某个地方了,没到服务端;完了客户端再次重试发送了第一次握手过去,服务端收到了,ok了,大家来回来去,三次握手建立了连接。


结果,尴尬的是,后来那个卡在哪儿的老的第一次握手发到了服务器,服务器直接就返回一个第二次握手,这个时候服务器开辟了资源准备客户端发送数据啥的,结果呢?客户端根本就不会理睬这个发回去的二次握手,因为之前都通信过了。


但是如果是三次握手,那个二次握手发回去,客户端发现根本不对,就会发送个复位的报文过去,让服务器撤销开辟的资源,别等着了。


因为3次握手就够了,不需要4次或者5次浪费资源了。



3.4 tcp断开连接的4次挥手

2020102717195784.png


TCP采用四次挥手来释放连接


第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入到FIN_WAIT_状态;


第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态;


第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态;


“挥手”是为了终止连接,TCP四次挥手的流程图如下(假设客户端触发Close)


第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,Client在经过2MSL时间也会进入CLOSED状态,完成四次挥手。


MSL:最长报文段寿命,IFC793定义MSL为2分钟,而Linux定义为30秒


TCP连接必须经过时间2MSL后才真正释放掉

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
6月前
|
网络协议 算法 网络性能优化
tcp拥塞控制整理
tcp拥塞控制整理
70 1
|
4月前
|
负载均衡 监控 网络协议
TCP四次挥手:为什么四次?原理大揭密!
**TCP四次挥手详解**:客户端发送FIN进入FIN-WAIT-1,服务器回ACK进CLOSE-WAIT;服务器发送FIN,客户端回ACK进TIME-WAIT,等待2MSL确保数据传输完毕,防止新旧连接混淆。四次挥手确保双方完全关闭连接,解决数据丢失问题。过多TIME-WAIT可通过负载均衡、优化关闭顺序或调整系统参数缓解。关注“软件求生”获取更多技术内容!
126 0
|
4月前
|
网络协议 程序员
为什么TCP需要三次握手?一文讲透!
**TCP三次握手摘要** TCP三次握手是建立可靠TCP连接的过程,包括: 1. 客户端发送SYN包,进入SYN_SENT状态。 2. 服务端回应SYN和ACK包,进入SYN_RCVD状态。 3. 客户端再次发送ACK包,双方进入ESTABLISHED状态,连接建立。 三次握手确保双方都能发送和接收数据,防止失效请求导致的资源浪费,并同步序列号以确保可靠性。
51 0
|
6月前
|
网络协议
怎么回答TCP的三次握手问题
怎么回答TCP的三次握手问题
31 0
|
6月前
|
网络协议 Linux 存储
深入理解Linux网络——TCP连接建立过程(三次握手源码详解)
一、相关实际问题 1. 为什么服务端程序都需要先listen一下 2. 半连接队列和全连接队列长度如何确定 3. “Cannot assign requested address”这个报错是怎么回事 4. 一个客户端端口可以同时用在两条连接上吗 5. 服务端半/全连接队列满了会怎么样 6. 新连接的soket内核对象是什么时候建立的 7. 建立一条TCP连接需要消耗多长时间 8. 服务器负载很正常,但是CPU被打到底了时怎么回事
|
网络协议 安全 Linux
TCP 三次握手与四次挥手深入探究(大图解)
TCP 三次握手与四次挥手深入探究(大图解)
563 1
|
缓存 网络协议 NoSQL
深入理解Linux网络——TCP连接建立过程(三次握手源码详解)-3
五、异常TCP建立情况 1)connect系统调用耗时失控 客户端在发起connect系统调用的的时候,主要工作就是端口选择。在选择的过程中有一个大循环
|
存储 缓存 网络协议
深入理解Linux网络——TCP连接建立过程(三次握手源码详解)-2
三、深入理解connect 客户端再发起连接的时候,创建一个socket,如何瞄准服务端调用connect就可以了,代码可以简单到只有两句。
深入理解Linux网络——TCP连接建立过程(三次握手源码详解)-2
|
存储 网络协议 Linux
深入理解Linux网络——TCP连接建立过程(三次握手源码详解)-1
一、相关实际问题 为什么服务端程序都需要先listen一下 半连接队列和全连接队列长度如何确定 “Cannot assign requested address”这个报错是怎么回事
|
网络协议 安全 Linux
Linux网络原理及编程(5)——第十五节 TCP的连接(三次握手、四次挥手)
本节我们来介绍TCP连接的建立和断开。我们主要介绍两个过程、两个状态。
203 0
Linux网络原理及编程(5)——第十五节 TCP的连接(三次握手、四次挥手)