欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > TCP

TCP

2025/2/22 3:15:00 来源:https://blog.csdn.net/2301_81259161/article/details/145662340  浏览:    关键词:TCP

TCP 是什么?

TCP ( Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

TCP 对应的应用层协议

FTP:定义了文件传输协议,使用 21 端口

TeInet:它是一种用于远程登录的端口,23端口

SMTP:定义了简单邮件传送协议,服务器开放的是 25 号端口

POP3:它是和 SMTP 对应,POPS 用于接收邮件

TCP 头部中有哪些信息?

源端口号(8 bit):用于标识发送方的应用程序进程

目的端口号(8 bit):用于标识接收方的应用程序进程

序列号(seq)(32 bit):传输方向上字节流的字节编号。初始时序号会被设置一个随机的初始                             值 (ISN),之后每次发送数据时,序号值 = ISN + 数据在整个字节流中的偏移

确认号(ack)(32 bit):接收方对发送方 TCP 报文段的响应,其值是收到的序号值 + 1,表示期望接收                             的下一个序列号

数据偏移(4 bit):标识首部有多少个 4 字节 * 首部长,最大为 15,即 60 字节

保留字段(6 bit):目前保留,值固定为 0

标志位(6 bit):

        URG: 标志紧急指针是否有效

        ACK: 标志确认号是否有效(确认报文段)

        PSH: 提示接收端应尽快从缓冲区读走数据

        RST: 表示要求对方重新建立连接(复位报文段)

        SYN: 表示请求建立一个连接(连接报文段)

        FIN: 表示关闭连接(断开报文段)

窗口大小(16 bit):接收窗口。用于告知对方(发送方)本方的缓冲区还能接收多少字节数据,用                                 于解决流量控制

校验和(16 bit):接收端用 CRC 校验整个报文段有无损坏

常见 TCP 的连接状态有哪些?

CLOSED:初始状态

LISTEN:服务器处于监听状态

SYN_SEND:客户端 socket 执行 CONNECT 连接,发送 SYN 包,进入此状态

SYN_RECV:服务端收到 SYN 包并发送服务端 SYN 包,进入此状态

ESTABLISH:表示连接建立。客户端发送了最后一个 ACK 包后进入此状态,服务端接收到 ACK                          包后进入此状态

FIN_WAIT_1:终止连接的一方(通常是客户机)发送了 FIN 报文后进入。等待对方 FIN.

CLOSE_WAIT:(假设服务器)接收到客户机 FIN 包之后等待关闭的阶段。在接收到对方的 FIN                                  包之后,自然是需要立即回复 ACK 包的,表示已经知道断开请求。但是本方                                 是否立即断开连接(发送 FIN 包)取决于是否还有数据需要发送给客户端,若                                 有,则在发送 FIN 包之前均为此状态

FIN_WAIT_2:此时是半连接状态,即有一方要求关闭连接,等待另一方关闭。客户端接收到服务                         器的 ACK 包,但并没有立即接收到服务端的 FIN 包,进入此状态

LAST_ACK:服务端发送最后的 FIN 包,等待最后的客户端 ACK 响应,进入此状态

TIME_WAIT:客户端收到服务端的 FIN 包,并立即发出 ACK 包做最后的确认,在此之后的                         2MSL 时间称为 TIME_WAIT 状态 

为何需要把 TCP/IP 协议栈分为 5 层 (或 7 层)?

ARPANET 的研制经验表明,对于复杂的计算机网络协议,其结构应该是层次式的。

分层的好处:

1)更易于理解网络通信的各个环节

2)功能模块化、抽象化,便于对网络功能进行扩展和定制

3)清晰的结构划分,便于分工协作

4)易于实现和维护

5)统一的标准接口,能促进标准化工作

什么是 TCP 粘包/拆包?发生的原因?怎么解决?

TCP粘包:指在进行TCP数据传输时,多个小的数据包被合并成一个大的数据包进行传输的现象。

TCP拆包:指一个大的数据包被拆分成多个小的数据包进行传输的现象。

原因:

1、应用程序向 TCP 套接字写入数据时,没有明确的边界划分,TCP 协议会根据自己的优化策略将数据进行合并或拆分。

2、数据包大小超过了网络传输的最大传输单元(MTU)

3、如果接收方读取数据的速度较慢,而发送方发送数据的速度较快,那么就可能会导致多个数据包在接收方的缓冲区中堆积,从而形成粘包现象。

解决方案:

1、消息定长。

2、在包尾部增加回车符或者换行符等特殊字符进行分割

3、自定义数据结构:分为消息头和数据,消息头中有字段说明紧随其后的数据有多大。

4、使用其他复杂的协议或框架。

为什么区域传送用 TCP 协议?

1、数据完整性和可靠性要求高:区域传送涉及传输整个区域的域名数据,数据量通常较大。

TCP 协议提供了可靠的数据传输机制,能够确保数据的完整性,保证所有的数据都能准确无误地从源服务器传输到目标服务器,如果使用了不可靠的协议,就可能会出现数据丢失或损坏地情况,导致域名解析出现错误。

2、连接的稳定性和有序性:区域传送通常是在 DNS 服务器之间进行的重要操作,需要一个稳定的连接来保证数据的持续传输。TCP 协议通过建立连接、维护连接状态等机制,提供了稳定的通信通道。在区域传送中域名数据的顺序是有意义的,如果数据乱序到达,可能会导致解析错误。

一个 TCP 连接可以对应几个 HTTP 请求?

一个 TCP 连接可以对应多个 HTTP 请求。在 HTTP/1.1中,默认情况下 TCP 连接是持久连接。这意味着在一个 TCP 连接建立后,可以在这个连接上发送多个 HTTP 请求和接收多个 HTTP 响应。这样可以减少建立和关闭连接的开销,提高性能。

一个 TCP 连接中 HTTP 请求发送可以一起发送吗(比如一起发三个请求,再三个响应一起接收)?

HTTP/1.1 存在一个问题,单个 TCP 连接在同一时刻只能处理一个请求,意思是说:两个请求的生命周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠。

在 HTTP/1.1 存在 Pipelining (管线化)技术允许客户端在一个连接上连续发送多个请求,而不必等待每个请求的响应。服务器会按照请求的顺序依次处理这些请求,并依次返回响应。在 HTTP2 中由于 Multiplexing (多路复用)技术的存在,多个 HTTP 请求可以在同一个 TCP 连接中并行进行。

那么在 HTTP/1.1 时代,浏览器是如何提高页面加载效率的呢?

主要有下面几点:

1、维持和服务器已经建立的 TCP 连接,在同一连接上顺序处理多个请求。

2、和服务器建立多个 TCP 连接

3、合并/压缩资源。

4、缓存机制

5、预加载和预取

6、优化页面加载顺序,让用户更快地看到部分页面内容

浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?

在 HTTP/1.0 中,一个服务器在发送完一个 HTTP 响应后,会断开 TCP 连接。但是这样每次请求都会重新建立和断开 TCP 连接,代价过大。所以虽然标准中没有设定,某些服务器对 Connection:keep-alive 的 Header 进行了支持。意思是说,完成这个 HTTP 请求之后,不要断开 HTTP 请求使用的 TCP 连接。

这样的好处是连接可以被重新利用,之后发送 HTTP 请求的时候不需要重新建立 TCP 连接,以及如果维持连接,那么 SSL 的开销也可以避免。

持久连接:既然维持 TCP 连接好处那么多,HTTP/1.1 就把 Connection 头写进标准,并且默认开启持久连接,除非请求中写明 Connection:close,那么浏览器和服务器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断掉。

默认情况下建立 TCP 连接不会断开,只有在请求报头中写明  Connection:close,才会在请求完成后关闭连接。

三次握手相关内容

三次握手(Three-way Handshake) 其实就是指建立一个 TCP 连接时,需要客户端和服务器总共发送 3 个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。

刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态,进行三次握手:

第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN(c),此时客户端处于 SYN_SEND 状态。

首部的同步位 SYN = 1,初始序号 seq = x, SYN = 1 的报文段不能携带数据,但要消耗掉一个序号。

第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s).同时会把客户端的 ISN + 1 作为 ack 的值,表示自己已经接收到了客户端的 SYN ,此时服务器处于 SYN_REVD 的状态。

在确认报文段中 SYN = 1 ,ACK = 1,确认号 ack = x + 1,初始序号 seq = y.

第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ack 的值,表示已经接收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时双方已建立起了连接。

确认报文段中 ACK = 1,确认号 ack = y + 1 ,序号 seq = x + 1(初始为 seq = x ,消耗了一个序号,所以第二个报文段要 + 1 ),ACK 报文段可以携带数据,不携带数据则不消耗序号。

发送第一个 SYN 的一端将执行主动打开(active open),接收这个 SYN 并发回下一个 SYN 的另一端执行被动打开(passive open)。

在 socket 编程中,客户端执行 connect() 时,将触发三次握手。 

为什么需要三次握手,两次不行吗?

弄清这个问题,我们需要先弄明白三次握手的目的是什么,能不能只用两次握手来达到同样的目的

第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。

第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力正常。

因此需要三次握手才能确认双方的接收与发送能力是否正常。

试想如果是用两次握手,则会出现下面这种情况:

如果客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。

后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出了一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一直等待客户端发送数据,浪费资源。

什么是半连接队列?

服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能出现丢包现象。

这里在补充一点关于 SYN-ACK 重传次数的问题:服务器发送完 SYN-ACK 包,如果未收到客户确认包,服务器会进行首次重传,等待一段时间仍未收到客户确认包,进行二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s, 2s, 4s, 8s......

ISN ( Inital Sequence Number ) 是固定的吗?

当一端为建立连接而发送它的 SYN 时,它为连接选择一个初始序号。ISN 随时间而变化,因此每个连接都将具有不同的 ISN 。ISN 可以看作是一个 32 比特的计数器,每 4ms 加 1 .这样选择序号的目的在于防止网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释。

三次握手的其中一个重要功能是客户端和服务端交换 ISN ,以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。

三次握手过程中可以携带数据吗?

其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据,为什么这样呢? 

大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。也就是说,第一次握手不可以携带数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没什么问题。

SYN 攻击是什么?

服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到 SYN 洪泛攻击。SYN 攻击就是 Client 在短时间内伪造大量不存在的 IP 地址,并向 Server 不断地发送 SYN 包,Server 则回复确认包,并等待 Clinet 确认,由于源地址不存在,因此 Server 需要不断重发直至超时,这些伪造的 SYN 包将长时间占用半连接队列,导致正常的 SYN 请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

检测 SYN 攻击非常方便,当你在服务器上看到大量的半连接状态时,特别是源 IP 地址是随机的,基本上可以断定这是一次 SYN 攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。

常见的防御 SYN 攻击的方法有如下几种:

1)缩短超时(SYN Timeout) 时间

2)增加最大半连接数

3)过滤网关防护

4)SYN cookies 技术

四次挥手相关内容

建立一个连接需要三次握手,而终止一个连接需要经过四次挥手。这由 TCP 的半关闭(half-close)造成的。所谓的半关闭,其实就是 TCP 提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。

TCP 连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务器均可主动发起挥手动作。

刚开始双方都处于 ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:

第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1状态。即发出连接释放报文段(FIN = 1,序号 seq = u),并停止在发送数据,主动关闭 TCP 连接,进入 FIN_WAIT1(终止等待 1)状态,等待服务端的确认。

第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经接收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。即服务端收到连接释放报文段后即发出确认报文段(ACK = 1, 确认号 ack = u + 1, 序号 seq = v),服务端进入 CLOSE_WAIT (关闭等待)状态,此时的 TCP 处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入 FIN_WAIT2(终止等待 2 )状态,等待服务端发出的连接释放报文段。

第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发送 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 状态。即服务端没有要向客户端发送的数据,服务端发送连接释放报文段(FIN = 1, ACK = 1, 序号 seq = w, 确认号 ack = u + 1), 服务端进入 LAST_ACK (最后确认)状态,等待客户端的确认。

第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务器的序列号值+1作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK = 1,seq = u + 1, ack = w + 1),客户端进入 TIME_WAIT ( 时间等待)状态。此时 TCP 未释放掉,需要经过时间等待计时器设置的时间 2MSL 后,客户端才进入 CLOSED 状态。

收到一个 FIN 只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入 TIME_WAIT 是正常的,服务器通常执行被动关闭,不会进入 TIME_WAIT 状态。

在 socket 编程中,任何一方执行 close() 操作即可产生挥手操作。

挥手为什么需要四次?

因为当服务端收到客户端的 SYN 连接请求报文后,可以直接发送 SYN + ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。但是关闭连接时,当服务端收到 FIN 报文时,很可能并不会立即关闭 SOCKET ,所以只能先回复一个 ACK 报文,告诉客户端,“你发的 FIN 报文我收到了”。只有等到我 服务端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送。故需要四次挥手。第二种回答,任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。

举个例子:A 和 B 打电话,通话即将结束后,A 说 “ 我没啥要说的了 ”,B 回答 “ 我知道了 ”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说 “ 我说完了 ”, A 回答 “ 知道了 ”,这样通话才算结束。

2MSL 等待状态?

TIME_WAIT 状态也称为 2MSL 等待状态。每个具体 TCP 实现必须选择一个报文段最大生存时间 MSL(Maximum Segment Lifetime), 它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的,因为 TCP 报文段以 IP 数据报在网络内传输,而 IP 数据报则有限制其生存时间的 TTL 字段。对一个具体实现所给定的 MSL 值,处理的原则是:当 TCP 执行一个主动关闭,并发回最后一个 ACK ,该连接必须在 TIME_WAIT 状态停留的时间为 2 倍 的 MSL 。这样可让 TCP 再次发送最后的 ACK 以防这个 ACK 丢失(另一端超时并重发最后的 FIN)。这种 2MSL 等待的另一个结果是这个 TCP 连接在 2MSL 等待期间,定义这个连接的插口(客户端的 IP 地址和端口号,服务器的 IP 地址和端口号)不能再被使用。这个连接只能在 2MSL 结束后才能再被使用。 

四次挥手释放连接时,等待 2MSL 的意义?

MSL 是 Maximum Segment Lifetime 的英文缩写,可译为 “ 最长报文段寿命 ”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

为了保证客户端发送的最后一个 ACK 报文段能够到达服务器。因为这个 ACK 有可能丢失,从而导致处在 LAST-ACK 状态的服务器收不到对 FIN-ACK 的确认报文。服务器会超时重传这个 FIN + ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待 2MSL ,而是再发送完 ACK 之后直接释放关闭,一旦这个 ACK 丢失的话,服务器就无法正常的进入关闭连接状态。

两个理由:

1) 保证客户端发送的最后一个 ACK 报文段能够到达服务端。这个 ACK 报文段有可能丢失,使得处于 LAST-ACK 状态的服务端收不到对已发送的 FIN + ACK 报文段的确认,服务端超时重传 FIN + ACK 报文段,而客户端能在 2MSL 时间内收到这个重传的 FIN + ACK 报文段,接着客户端重传一次确认,重新启动 2MSL 计时器,最后客户端和服务端都进入 CLOSED 状态,若客户端在 TIME_WAIT 状态不等待一段时间,而是发送完 ACK 报文段后立即释放连接,则无法收到服务端重传的 FIN + ACK 报文段,所以不会再发送一次确认报文段,则服务端无法正常进入到 CLOSED 状态。

2)防止 “ 已失效的连接请求报文段 ” 出现在本连接中。客户端在发送完最后一个 ACK 报文段后,再经过 2MSL ,就可以使本连接持续时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

TCP 协议如何保证可靠传输?

确认和重传:接收方收到报文就会确认,发送方发送一段时间后没有收到确认就会重传。

数据校验:TCP 报文头有校验和,用于校验报文是否损坏

数据合理分片和排序:TCP 会按最大传输单元(MTU) 合理分片,接收方会缓存未按序到达的数据,重新排序后交给应用层。而 UDP :IP 数据报大于 1500 字节,大于 MTU 。这个时候发送方的 IP 层就需要分片,把数据报分成若干片,使得每一片都小于 MTU 。而接收方 IP 层则需要进行数据报的重组。由于 UDP 的特性,某一片数据丢失时,接收方便无法重组数据报,导致丢弃整个 UDP 数据报。

流量控制:当接收方来不及处理发送方的数据,能通过滑动窗口,提示发送方降低发送的速率,防止包丢失。

拥塞控制:当网络拥塞时,通过拥塞窗口,减少数据的发送,防止包丢失。

你了解流量控制原理吗?

目的是接收方通过 TCP 头窗口字段告知发送方本方可接收的最大数据量,用以解决发送速率过快导致接收方不能接收的问题。所以流量控制是点对点控制。

TCP 是双工协议,双方可以同时通信,所以发送方接收方各自维护一个发送窗和接收窗。

发送窗:用来限制发送方可以发送的数据大小,其中发送窗口的大小由接收端返回的 TCP 报文段中窗口字段来控制,接收方通过此字段告知发送方自己的缓冲(受系统、硬件等限制)大小。

接受窗口:用来标记可以接收的数据大小。

TCP 是流数据,发送出去的数据流可以被分为以下四部分:已发送且被确认部分 | 已发送未被确认部分 | 未发送但可发送部分 | 不可发送部分,其中发送窗 = 已发送未确认部分 + 未发送但可发送部分。接收到的数据流可分为:已接收 | 未接收但准备接收 | 未接收不准备接收。接收窗 = 未接收但准备接收部分

发送窗内数据只有当接收到接收端某段发送数据的 ACK 响应时才移动发送窗,左边缘紧贴刚被确认的数据。接收窗也只有接收到数据且最左侧连续时才移动接收窗口。

TCP 利用滑动窗口实现流量控制的机制?

流量控制是为了控制发送方发送速率,保证接收方来得及接收。

TCP 利用滑动窗口实现流量控制。

TCP 中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为 0 时,发送方一般不能再发送数据报,但有两种情况除外,一种情况是可以发送紧急数据。例如,允许用户终止再远端机上的运行进程。另一种情况是发送方可以发送一个 1 字节的数据报来通知接收方重新声明他希望接收的下一字节及发送方的滑动窗口大小。

可以解释一下 RTO,RTT 和超时重传分别是什么吗?

超时重传:发送端发送报文后若长时间未收到确认的报文则需要重发该报文。

可能以下几种情况:

1)发送的数据没能到达接收端,所以对方没有响应

2)接收端接收到数据,但是 ACK 报文在返回过程中丢失

3)接收端拒绝或丢弃数据

RTO : 从上一次发送数据,因为长期没有收到 ACK 响应,到下一次重发之间的时间。就是重传间隔。

通常每次重传 RTO 是前一次重传间隔的两倍,计算单位通常是 RTT. 例如:1RTT, 2RTT, 4RTT , 8RTT......重传次数到达上限之后停止重传

RTT : 数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。大小不稳定。

拥塞控制原理听说过吗?

拥塞控制目的是防止数据过多注入网络中导致网络资源(路由器、交换机等)过载。因为拥塞控制设计网络链路全局,所以属于全局控制。控制拥塞使用拥塞窗口。

TCP 拥塞控制算法:

慢启动 & 拥塞避免:先试探网络拥塞程度再逐渐增大拥塞窗口。每次收到确认后拥塞窗口翻倍,直到达到阈值 ssthresh, 这部分是慢启动过程。达到阈值后每次以一个 MSS 单位增长拥塞窗口大小,当发生拥塞(超时未收到确认),将阈值减为原先一半,继续执行线性增加,这个过程为拥塞避免。

如何区分流量控制和拥塞控制?

流量控制属于双方协商;拥塞控制涉及通信链路全局。

流量控制需要通信双方各维护一个发送窗、一个接收窗,对任意一方,接收窗大小由自身决定,发送窗大小由接收方响应的 TCP 报文段中窗口值确定;

拥塞控制的拥塞窗口大小变化由试探性发送一定数据量数据探查网络状况后而自适应调整。

是实际最终发送窗口 = min { 流控发送窗口,拥塞窗口 }。

一台机器能够使用的端口号上限是多少,是否可以修改?如果想要用的端口超过这个限制怎么办?

65536. 因为 TCP 的报文头部中源端口号和目的端口号的长度是 16 位,也就是可以表示 2^16 =65536 个不同的端口号,因此 TCP 可供识别的端口号最多只有 65536 个。但是由于 0 到 1023 是知名服务端口,所以实际上对于服务器来说,在一定程度上可供普通应用程序选择的端口号数量会减少 1024 个。服务器可打开端口号也受限于 Linux 可以打开的文件数量。

可以通过修改系统参数 MaxUserPort 来调整用户可使用的端口范围上限,从而在一定程度上影响服务器可使用的端口号数量。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词