近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题

原标题:近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题 来源:幼林coding 责坏融资担保公司 来源:幼林coding 不管面试 Java 、C/C 、Python 等开发岗位, TCP 的知识点能够说是的...


原标题:近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题

来源:幼林coding

责坏融资担保公司

来源:幼林coding

不管面试 Java 、C/C 、Python 等开发岗位, TCP 的知识点能够说是的必问的了。

任 TCP 虐吾千百遍,吾仍待 TCP 如初恋。

遥想以前校招往往因 TCP 面试题被刷,真是又喜欢又狠….

以前不会能够,今天就让吾们来清除这份恐惧,微乐着果敢的面对它吧!因而本文清理了关于 TCP 三次握手和四次挥手的面试题型,跟行家一首探讨探讨。

PS:本次文章不涉及 TCP 流量控制、拥塞控制、郑重性传输等方面知识,这些留在下篇哈!

PS:本次文章不涉及 TCP 流量控制、拥塞控制、郑重性传输等方面知识,这些留在下篇哈!

01 TCP 基本意识

瞧瞧 TCP 头格式

瞧瞧 TCP 头格式

吾们先来望望 TCP 头的格式,标注颜色的外示与本文有关比较大的字段,其他字段不做详细阐述。

TCP 头格式

序列号:在竖立连接时由计算机生成的随机数行为其初首值,经过 SYN 包传给授与端主机,每发送一次数据,就「累添」一次该「数据字节数」的大幼。用来解决网络包乱序题目。

确认答答号:指下一次「憧憬」收到的数据的序列号,发送端收到这个确认答答以后能够认为在这个序号以前的数据都已经被平常授与。用来解决不丢包的题目。

控制位:

为什么必要 TCP 制定?TCP 做事在哪一层?

为什么必要 TCP 制定?TCP 做事在哪一层?

IP 层是「不走靠」的,它不保证网络包的交付、不保证网络包的挨次交付、也不保证网络包中的数据的完善性。

OSI 参考模型与 TCP/IP 的有关

倘若必要保障网络数据包的郑重性,那么就必要由表层(传输层)的 TCP 制定来负责。

由于 TCP 是一个做事在传输层的郑重数据传输的服务,它能确保授与端授与的网络包是无损坏、无阻隔、非冗余和挨次的。

什么是 TCP ?

什么是 TCP ?

TCP 是面向连接的、郑重的、基于字节流的传输层通信制定。

什么是 TCP 连接?

什么是 TCP 连接?

吾们来望望 RFC 793 是如何定义「连接」的:

Connections:

The reliability and flow control mechanisms described above require that TCPs initialize and maintain certain status information for each data stream.

The combination of this information, including sockets, sequence numbers, and window sizes, is called a connection.

浅易来说就是,用于保证郑重性和流量控制维护的某些状态新闻,这些新闻的组相符,包括Socket、序列号和窗口大幼称为连接。

因而吾们能够晓畅,竖立一个 TCP 连接是必要客户端与服务器端达成上述三个新闻的共识。

如何唯一确定一个 TCP 连接呢?

如何唯一确定一个 TCP 连接呢?

TCP 四元组能够唯一实在定一个连接,四元组包括如下:

TCP 四元组

源地址和主意地址的字段(32位)是在 IP 头部中,作用是经过 IP 制定发送报文给对方主机。

源端口和主意端口的字段(16位)是在 TCP 头部中,作用是告诉 TCP 制定答该把报文发给哪个进程。

有一个 IP 的服务器监听了一个端口,它的 TCP 的最大连接数是众少?

有一个 IP 的服务器监听了一个端口,它的 TCP 的最大连接数是众少?

服务器清淡固定在某个本地端口上监听,期待客户端的连接乞求。

因此,客户端 IP 和 端口是可变的,其理论值计算公式如下:

对 IPv4,客户端的 IP 数最众为 2 的 32 次方,客户端的端口数最众为 2 的 16 次方,也就是服务端单机最大 TCP 连接数,约为 2 的 48 次方。

自然,服务端最大并发 TCP 连接数远不及达到理论上限。

UDP 和 TCP 有什么区别呢?别离的行使场景是?

UDP 和 TCP 有什么区别呢?别离的行使场景是?

UDP 不挑供复杂的控制机制,行使 IP 挑供面向「无连接」的通钦佩务。

UDP 制定真的专门简,头部只有 8 个字节( 64 位),UDP 的头部格式如下:

UDP 头部格式

TCP 和 UDP 区别:

1. 连接

2. 服务对象

3. 郑重性

4. 拥塞控制、流量控制

5. 首部支付

TCP 和 UDP 行使场景:

由于 TCP 是面向连接,能保证数据的郑重性交付,因此频繁用于:

由于 UDP 面向无连接,它能够随时发送数据,再添上UDP本身的处理既浅易又高效,

因此频繁用于:

为什么 UDP 头部异国「首部长度」字段,而 TCP 头部有「首部长度」字段呢?

为什么 UDP 头部异国「首部长度」字段,而 TCP 头部有「首部长度」字段呢?

因为是 TCP 有可变长的「选项」字段,而 UDP 头部长度则是不会转折的,无需众一个字段去记录 UDP 的首部长度。

为什么 UDP 头部有「包长度」字段,而 TCP 头部则异国「包长度」字段呢?

为什么 UDP 头部有「包长度」字段,而 TCP 头部则异国「包长度」字段呢?

先说说 TCP 是如何计算负载数据长度:

其中 IP 总长度 和 IP 首部长度,在 IP 首部格式是已知的。TCP 首部长度,则是在 TCP 首部格式已知的,因而就能够求得 TCP 数据的长度。

行家这时就稀奇了问:“ UDP 也是基于 IP 层的呀,那 UDP 的数据长度也能够经过这个公式计算呀?为何还要有「包长度」呢?”

这么一问,实在感觉 UDP 「包长度」是冗余的。

由于为了网络设备硬件设计和处理方便,首部长度必要是 4字节的整数倍。

倘若去失踪 UDP 「包长度」字段,那 UDP 首部长度就不是 4 字节的整数倍了,因而幼林觉得这能够是为了补全 UDP 首部长度是 4 字节的整数倍,才添添了「包长度」字段。

02 TCP 连接竖立

TCP 三次握手过程和状态变迁

TCP 三次握手过程和状态变迁

TCP 是面向连接的制定,因而行使 TCP 前必须先竖立连接,而竖立连接是经过三次握手而进走的。

TCP 三次握手

第一个报文—— SYN 报文

第二个报文 —— SYN ACK 报文

第三个报文 —— ACK 报文

从上面的过程能够发现第三次握手是能够携带数据的,前两次握手是不能够携带数据的,这也是面试常问的题。

一旦完善三次握手,两边都处于 ESTABLISHED 状态,此致连接就已竖立完善,客户端和服务端就能够相互发送数据了。

如何在 Linux 编制中查望 TCP 状态?

如何在 Linux 编制中查望 TCP 状态?

TCP 的连接状态查望,在 Linux 能够经过 netstat -napt 命令查望。

TCP 连接状态查望

为什么是三次握手?不是两次、四次?

为什么是三次握手?不是两次、四次?

坚信行家比较常回答的是:“由于三次握手才能保证两边具有授与和发送的能力。”

这回答是没题目,但这回答是单方的,并异国说出主要的因为。

在前线吾们晓畅了什么是 TCP 连接:

因而,主要的是为什么三次握手才能够初首化Socket、序列号和窗口大幼并竖立 TCP 连接。

接下来以三个方面分析三次握手的因为:

因为一:避免历史连接

吾们来望望 RFC 793 指出的 TCP 连接行使三次握手的主要因为:

The principle reason for the three-way handshake is to prevent old duplicate connection initiations from causing confusion.

浅易来说,三次握手的主要因为是为了防止旧的重复连接初首化造成紊乱。

网络环境是错综复杂的,往往并不是如吾们憧憬的相通,先发送的数据包,就先到达现在标主机,逆而它很骚,能够会由于网络拥堵等杂乱无章的因为,会使得旧的数据包,先到达现在标主机,那么这栽情况下 TCP 三次握手是如何避免的呢?

三次握手避免历史连接

客户端不息发送众次 SYN 竖立连接的报文,在网络拥堵等情况下:

倘若是两次握手连接,就不及判定现在连接是否是历史连接,三次握手则能够在客户端(发送方)准备发送第三次报文时,客户端因有有余的上下文来判定现在连接是否是历史连接:

因而, TCP 行使三次握手竖立连接的最主要因为是防止历史连接初首化了连接。

因为二:同步两边初首序列号

TCP 制定的通信两边, 都必须维护一个「序列号」, 序列号是郑重传输的一个关键因素,它的作用:

可见,序列号在 TCP 连接中占有着专门主要的作用,因而当客户端发送携带「初首序列号」的 SYN 报文的时候,必要服务端回一个 ACK 答答报文,外示客户端的 SYN 报文已被服务端成功授与,那当服务端发送「初首序列号」给客户端的时候,照样也要得到客户端的答答回答,云云一来一回,才能确保两边的初首序列号能被郑重的同步。

四次握手与三次握手

四次握手其实也能够郑重的同步两边的初首化序号,但由于第二步和第三步能够优化成一步,因而就成了「三次握手」。

而两次握手只保证了一方的初首序列号能被对方成功授与,没手段保证两边的初首序列号都能被确认授与。

因为三:避免资源铺张

倘若只有「两次握手」,当客户端的 SYN 乞求连接在网络中壅塞,客户端异国授与到 ACK 报文,就会重新发送 SYN ,由于异国第三次握手,服务器不清新客户端是否收到了本身发送的竖立连接的 ACK 确认信号,因而每收到一个 SYN 就只能先主动竖立一个连接,这会造成什么情况呢?

倘若客户端的 SYN 壅塞了,重复发送众次 SYN 报文,那么服务器在收到乞求后就会竖立众个冗余的无效链接,造成不消要的资源铺张。

两次握手会造成资源铺张

即两次握手会造成新闻滞留情况下,服务器重复批准无用的连接乞求 SYN 报文,而造成重复分配资源。

幼结

TCP 竖立连接时,经过三次握手能防止历史连接的竖立,能缩短两边不消要的资源支付,能协助两边同步初首化序列号。序列号能够保证数据包不重复、不屏舍和挨次传输。

不行使「两次握手」和「四次握手」的因为:

为什么客户端和服务端的初首序列号 ISN 是不相通的?

为什么客户端和服务端的初首序列号 ISN 是不相通的?

由于网络中的报文会延宕、会复制重发、也有能够丢失,云云会造成的分歧连接之间产生互相影响,因而为了避免互相影响,客户端和服务端的初首序列号是随机且分歧的。

初首序列号 ISN 是如何随机产生的?

初首序列号 ISN 是如何随机产生的?

首首 ISN 是基于时钟的,每 4 毫秒 1,转一圈要 4.55 个幼时。

RFC1948 中挑出了一个较益的初首化序列号 ISN 随机生成算法。

ISN = M F (localhost, localport, remotehost, remoteport)

既然 IP 层会分片,为什么 TCP 层还必要 MSS 呢?

既然 IP 层会分片,为什么 TCP 层还必要 MSS 呢?

吾们先来意识下 MTU 和 MSS

MTU 与 MSS

倘若TCP 的整个报文(头部 数据)交给 IP 层进走分片,会有什么变态呢?

当 IP 层有一个超过 MTU 大幼的数据(TCP 头部 TCP 数据)要发送,那么 IP 层就要进走分片,把数据分片成若干片,保证每一个分片都幼于 MTU。把一份 IP 数据报进走分片以后,由现在标主机的 IP 层来进走重新拼装后,在交给上一层 TCP 传输层。

这望首来整齐有序,但这存在隐患的,那么当倘若一个 IP 分片丢失,整个 IP 报文的一切分片都得重传。

由于 IP 层本身异国超时重传机制,它由传输层的 TCP 来负责超时和重传。

当授与方发现 TCP 报文(头部 数据)的某一片丢失后,则不会反响 ACK 给对方,那么发送方的 TCP 在超时后,就会重发「整个 TCP 报文(头部 数据)」。

因此,能够得知由 IP 层进走分片传输,是专门异国效果的。

因而,为了达到最佳的传输效能 TCP 制定在竖立连接的时候清淡要商议两边的 MSS 值,当 TCP 层发现数据超过 MSS 时,则就先会进走分片,自然由它形成的 IP 包的长度也就不会大于 MTU ,自然也就不消 IP 分片了。

握手阶段商议 MSS

经过 TCP 层分片后,倘若一个 TCP 分片丢失后,图片中心进走重发时也是以 MSS 为单位,而不消重传一切的分片,大大添添了重传的效果。

什么是 SYN 抨击?如何避免 SYN 抨击?

什么是 SYN 抨击?如何避免 SYN 抨击?

SYN 抨击

吾们都晓畅 TCP 连接竖立是必要三次握手,倘若抨击者短时间捏造分歧 IP 地址的 SYN 报文,服务端每授与到一个 SYN 报文,就进入SYN_RCVD 状态,但服务端发送出去的 ACK SYN 报文,无法得到未知 IP 主机的 ACK 答答,久而久之就会占满服务端的 SYN 授与队列(未连接队列),使得服务器不及为平常用户服务。

SYN 抨击

避免 SYN 抨击手段一

其中一栽解决手段是经过修改 Linux 内核参数,控制队列大幼和当队列满时答做什么处理。

避免 SYN 抨击手段二

吾们先来望下Linux 内核的 SYN (未完善连接竖立)队列与 Accpet (已完善连接竖立)队列是如何做事的?

平常流程

平常流程:

行使程序过慢

行使程序过慢:

受到 SYN 抨击

受到 SYN 抨击:

tcp_syncookies 的手段能够答对 SYN 抨击的手段:

tcp_syncookies 答对 SYN 抨击

03 TCP 连接断开

TCP 四次挥手过程和状态变迁

TCP 四次挥手过程和状态变迁

天下异国不散的宴席,对于 TCP 连接也是云云, TCP 断开连接是经过四次挥手手段。

两边都能够主动断开连接,断开连接后主机中的「资源」将被开释。

客户端主动关闭连接 —— TCP 四次挥手

你能够望到,每个倾向都必要一个 FIN 和一个 ACK,因此清淡被称为四次挥手。

这边一点必要仔细是:主动关闭连接的,才有 TIME_WAIT 状态。

为什么挥手必要四次?

为什么挥手必要四次?

再来回顾下四次挥手两边发 FIN 包的过程,就能理解为什么必要四次了。

从上面过程可知,服务端清淡必要期待完善数据的发送和处理,因而服务端的 ACK 和 FIN 清淡都会睁开发送,从而比三次握手导致众了一次。

为什么 TIME_WAIT 期待的时间是 2MSL?

为什么 TIME_WAIT 期待的时间是 2MSL?

MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被屏舍。由于 TCP 报文基于是 IP 制定的,而 IP 头中有一个 TTL 字段,是 IP 数据报能够经过的最大路由数,每经过一个处理他的路由器此值就减 1,当此值为 0 则数据报将被屏舍,同时发送 ICMP 报文告诉源主机。

MSL 与 TTL 的区别:MSL 的单位是时间,而 TTL 是经过路由跳数。因而 MSL 答该要大于等于 TTL 消耗为 0 的时间,以确保报文已被自然湮灭。

TIME_WAIT 期待 2 倍的 MSL,比较相符理的注释是:网络中能够存在来自愿送方的数据包,当这些发送方的数据包被授与方处理后又会向对方发送反响,因而一来一回必要期待 2 倍的时间。

比如,倘若被动关闭方异国收到断开连接的末了的 ACK 报文,就会触发超时重发 Fin 报文,另一方授与到 FIN 后,会重发 ACK 给被动关闭方, 一来一去正益 2 个 MSL。

2MSL 的时间是从客户端授与到 FIN 后发送 ACK 最先计时的。倘若在 TIME-WAIT 时间内,由于客户端的 ACK 异国传输到服务端,客户端又授与到了服务端重发的 FIN 报文,那么 2MSL 时间将重新计时。

在 Linux 编制里 2MSL 默认是 60 秒,那么一个 MSL 也就是 30 秒。Linux 编制中止在 TIME_WAIT 的时间为固定的 60 秒。

其定义在 Linux 内核代码里的名称为 TCP_TIMEWAIT_LEN:

倘若要修改 TIME_WAIT 的时间长度,只能修改 Linux 内核代码里 TCP_TIMEWAIT_LEN 的值,并重新编译 Linux 内核。

为什么必要 TIME_WAIT 状态?

为什么必要 TIME_WAIT 状态?

主动发首关闭连接的一方,才会有 TIME-WAIT 状态。

必要 TIME-WAIT 状态,主要是两个因为:

因为一:防止旧连接的数据包

倘若 TIME-WAIT 异国期待时间或时间过短,被延宕的数据包抵达后会发生什么呢?

授与到历史数据的变态

因而,TCP 就设计出了这么一个机制,经过 2MSL 这个时间,足以让两个倾向上的数据包都被屏舍,使得正本连接的数据包在网络中都自然湮灭,再展现的数据包必定都是新竖立连接所产生的。

因为二:保证连接准确关闭

在 RFC 793 指出 TIME-WAIT 另一个主要的作用是:

TIME-WAIT - represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request.

也就是说,TIME-WAIT 作用是期待有余的时间以确保末了的 ACK 能让被动关闭方授与,从而协助其平常关闭。

倘若 TIME-WAIT 异国期待时间或时间过短,断开连接会造成什么题目呢?

异国确保平常断开的变态

倘若 TIME-WAIT 期待有余长的情况就会遇到两栽情况:

因而客户端在 TIME-WAIT 状态期待 2MSL 时间后,就能够保证两边的连接都能够平常的关闭。

TIME_WAIT 过众有什么危害?

TIME_WAIT 过众有什么危害?

倘若服务器有处于 TIME-WAIT 状态的 TCP,则表明是由服务器方主动发首的断开乞求。

过众的 TIME-WAIT 状态主要的危害有两栽:

第二个危害是会造成厉重的效果的,要晓畅,端口资源也是有限的,清淡能够开启的端口为 32768~61000,也能够经过如下参数竖立指定

倘若服务端 TIME_WAIT 状态过众,占满了一切端口资源,则会导致无法创建新连接。

如何优化 TIME_WAIT?

如何优化 TIME_WAIT?

这边给出优化 TIME-WAIT 的几个手段,都是有利有弊:

手段一:net.ipv4.tcp_tw_reuse 和 tcp_timestamps

如下的 Linux 内核参数开启后,则能够复用处于 TIME_WAIT 的 socket 为新的连接所用。

行使这个选项,还有一个前挑,必要掀开对 TCP 时间戳的声援,即

这个时间戳的字段是在 TCP 头部的「选项」里,用于记录 TCP 发送方的现在时间戳和从对端授与到的最新时间戳。

由于引入了时间戳,吾们在前线挑到的 2MSL 题目就不复存在了,由于重复的数据包会由于时间戳过期被自然屏舍。

温馨挑醒:net.ipv4.tcp_tw_reuse要慎用,由于行使了它就必然要掀开时间戳的声援 net.ipv4.tcp_timestamps,当客户端与服务端主机时间分歧步时,客户端的发送的新闻会被直接拒绝失踪。幼林在做事中就遇到过。。。排查了专门的久

手段二:net.ipv4.tcp_max_tw_buckets

这个值默认为 18000,当编制中处于 TIME_WAIT 的连接一旦超过这个值时,编制就会将一切的 TIME_WAIT 连接状态重置。

这个手段过于暴力,而且治标不治本,带来的题目远比解决的题目众,不选举行使。

手段三:程序中行使 SO_LINGER

吾们能够经过竖立 socket 选项,来竖立调用 close 关闭连接走为。

倘若l_onoff为非 0, 且l_linger值为 0,那么调用close后,会立该发送一个RST标志给对端,该 TCP 连接将跳过四次挥手,也就跳过了TIME_WAIT状态,直接关闭。

但这为跨越TIME_WAIT状态挑供了一个能够,不过是一个专门危险的走为,不值得挑倡。

倘若已经竖立了连接,但是客户端突然展现故障了怎么办?

倘若已经竖立了连接,但是客户端突然展现故障了怎么办?

TCP 有一个机制是保活机制。这个机制的原理是云云的:

定义一个时间段,在这个时间段内,倘若异国任何连接有关的运动,TCP 保活机制会最先作用,每隔一个时间阻隔,发送一个探测报文,该探测报文包含的数据专门少,倘若不息几个探测报文都异国得到反响,则认为现在的 TCP 连接已经物化亡,编制内核将舛讹新闻告诉给表层行使程序。

在 Linux 内核能够有对答的参数能够竖立保活时间、保活探测的次数、保活探测的时间阻隔,以下都为默认值:

也就是说在 Linux 编制中,最少必要经过 2 幼时 11 分 15 秒才能够发现一个「物化亡」连接。

这个时间是有点长的,吾们也能够按照实际的需求,对以上的保活有关的参数进走竖立。

倘若开启了 TCP 保活,必要考虑以下几栽情况:

第一栽,对端程序是平常做事的。当 TCP 保活的探测报文发送给对端, 对端会平常反响,云云 TCP 保活时间会被重置,期待下一个 TCP 保活时间的到来。

第二栽,对端程序休业并重启。当 TCP 保活的探测报文发送给对端后,对端是能够反响的,但由于异国该连接的有效新闻,会产生一个 RST 报文,云云很快就会发现 TCP 连接已经被重置。

第三栽,是对端程序休业,或对端由于其他因为导致报文不走达。当 TCP 保活的探测报文发送给对端后,石沉大海,异国反响,不息几次,达到保活探测次数后,TCP 会报告该 TCP 连接已经物化亡。

03 Socket 编程

针对 TCP 答该如何 Socket 编程?

针对 TCP 答该如何 Socket 编程?

基于 TCP 制定的客户端和服务器做事

这边必要仔细的是,服务端调用 accept 时,连接成功了会返回一个已完善连接的 socket,后续用来传输数据。

因而,监听的 socket 和真实用来传送数据的 socket,是「两个」 socket,一个叫作监听 socket,一个叫作已完善连接 socket。

成功连接竖立之后,两边最先经过 read 和 write 函数来读写数据,就像去一个文件流内里写东西相通。

listen 时候参数 backlog 的意义?

listen 时候参数 backlog 的意义?

Linux内核中会维护两个队列:

SYN 队列 与 Accpet 队列

在早期 Linux 内核 backlog 是 SYN 队列大幼,也就是未完善的队列大幼。

在 Linux 内核 2.2 之后,backlog 变成 accept 队列,也就是已完善连接竖立的队列长度,因而现在清淡认为 backlog 是 accept 队列。

accept 发送在三次握手的哪一步?

accept 发送在三次握手的哪一步?

吾们先望望客户端连接服务端时,发送了什么?

客户端连接服务端

从上面的描述过程,吾们能够得知客户端 connect 成功返回是在第二次握手,服务端 accept 成功返回是在三次握手成功之后。

客户端调用 close 了,连接是断开的流程是什么?

客户端调用 close 了,连接是断开的流程是什么?

吾们望望客户端主动调用了 close,会发生什么?

客户端调用 close 过程

巨人的肩膀

[1] 趣谈网络制定专栏.刘超.极客时间.

[2] 网络编程实战专栏.盛延敏.极客时间.

[3] 计算机网络-自顶向动手段.陈鸣 译.死板工业出版社

[4] TCP/IP详解 卷1:制定.范建华 译.死板工业出版社

[5] 图解TCP/IP.竹下隆史.人民邮电出版社

[6] https://www.rfc-editor.org/rfc/rfc793.html

[7] https://draveness.me/whys-the-design-tcp-three-way-handshake

[9] https://draveness.me/whys-the-design-tcp-time-wait

  德系车企三巨头2019年均实现盈利

  一家原本资金链断裂的科技公司,在无锡市新吴法院的“放水养鱼”之下,不仅成功输血起死回生,还使疫情期间员工工资得到了保障。近日,该公司主动申请将所涉68件劳动报酬纠纷诉讼相应的款项197万余元支付至新吴法院账户,员工吃了“定心丸”。

原标题:湖北交管局:不得擅自对离汉人员额外增加出具各类证明的要求

相关文章