传输层协议(5):TCP 连接(下-2)

思科实验10.传输层:TCP连接 TCP连接基础知识实验目的实验流程1.设计拓扑2.配置主机IP地址3.配置路由器4.配置服务器5.验证连通性6.观察tcp报文 基础知识 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK,并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的 阅读详情

5.2.12 收到对方报文

上一小节我们讲述了 TCP 的一方等待另一方报文超时的情形,那真是望眼欲穿、黯然神伤。那么,如果没有超时,在期望时间内收到了对方的报文呢?是不是就是欢呼雀跃一下子扑进对方的怀抱呢?

来敲门的不一定都是幸福,也有可能是狼外婆。所以,TCP 收到对端的报文时,首先要做的就是合法性检查,然后再根据检查情况,决定下一步的动作。至于什么样的报文是合法的,则与当是的 TCP 的状态有关。

 

5.2.12.1 CLOSED 状态

CLOSED 状态实际上并不是 TCP 连接的一个“真实”的状态,或者说处于 CLOSED 状态的 TCP 连接并不存在。我们知道,从“物理”角度来说,所谓 TCP 连接,指的就是一块相应的 TCB 内存块。处于CLOSED 状态的 TCP 连接,其所对应的 TCB 内存块其实已经被删除了,也就是说这样的 TCP 连接,实际上并不存在——只是我们处于表达上的方便,还是称呼“处于 CLOSED 状态的 TCP 连接”而已。

TCB 内存块已经被删除了,但是 TCP 协议栈还在。所以处于 CLOSED 状态的 TCP 连接,仍然可以接收报文,也仍然可以做相应的处理,这与关闭 TCP 协议栈的情形是不同的。

CLOSED 状态的 TCP 连接,无论收到什么报文,它都会将其丢弃。如果所接收的报文,不是 RST 报文,TCP 还会回给对方1个 RST 报文(如果所接收的是 RST 报文,则只丢弃不回应)。

TCP 所回应的 RST 报文,与其所接收的报文中的 ACK 标志位有关:

(1) 如果所接收报文的 ACK 标志位为“0”,则 RST 报文的格式为:

<SEQ = 0> <AKN = SEG.SEQ + SEG.LEN> <CTL = RST, ACK>

(2) 如果所接收报文的 ACK 标志位为“1”,则 RST 报文的格式为:

<SEQ = SEG.ACK> <CTL = RST>

 

这样表达的报文格式,需要稍微解释一下,如图5-52所示:

 

 图5-52 报文格式的解释

 

图5-52解释的应该比较清楚了,笔者就不再啰嗦了。下文的报文格式,会继续采用这种方式来表达。

 

5.2.12.2 通用处理思路

除了 CLOSED 状态,其他状态的 TCP 连接处理其所接收报文,都遵循一个通用的处理思路,如图5-53所示:

 

 图5-53 TCP 通用处理思路(抽象)

 

图5-53是通用处理思路的一个抽象表达。TCP 收到1个报文时,它首先会做参数的合法性校验,然后查看该报文是否是 RST 报文。如果报文的参数合法,并且也不是 RST 报文,那么接下来就看该报文的行为是否合法。

什么叫一个报文的行为呢?就是综合该报文的标志字段及数据长度,“拟人”出该报文的行为。比如“SYN 标志 = 1,数据长度 = 0”,这个报文的行为就是“请求创建连接”。

不同状态的 TCP,它期望的所接收报文的行为是不同的。比如处于 ESTABLISHED 状态的 TCP,对方可以发送数据给它,也可以发送关闭连接的请求给它,这些都没有超出该 TCP 的期望。但是,如果对方发送了一个创建连接的请求报文,那么此行为显然超出了该 TCP 的期望。

TCP 对于所接收报文的“非法参数”、“RST 报文”、“非法行为”、“合法行为”等情形,都有对应的处理。一般来说,针对前三种情形,TCP 做了相应处理以后,最后都是将其所接收到的报文丢弃。而合法行为的报文,TCP 处理完以后,如果该报文没有包含数据,那其实也是将其丢弃;如果包含数据,TCP 会将该数据暂时存放在自己的缓存中以便交给用户。

图5-53只是一个抽象的表达,更具体的 TCP 通用处理思路,如图5-54所示:

 

图5-54 TCP 通用处理思路

 

图5-54,第一眼看起来可能会崩溃。实际上将这个图做一个归纳,就比较好理解了:图中的“2(S/A/L 是否合法)、4(S/C 是否合法)、5(优先级是否合法)”,都是属于图5-53所说的“参数是否合法”——这样一来,就比较清晰了,图5-54仍然表达的 TCP 对于所接收报文的“非法参数”、“RST 报文”、“非法行为”、“合法行为”等情形的处理流程。另外,图5-54中画了两个框“丢弃所接收的报文”,着只是为了构图的清晰,别无它意,两个方框其实应该是一个方框。

下面就让我们从图5-54中的第1个判断点开始,进一步分析 TCP 接收到报文时的通用处理思路。

 

1)ACK 判断点

图5-54与图5-53相比,最大的不同是:图5-54中多了“是否存在 ACK”的判断点,并且“处理 NO ACK”的方框是一个虚框。

“是否存在 ACK”,指的是所接收报文中的 ACK 标志是否为“1”。并不是每个报文的 ACK 都应该为“1”,比如第1次请求创建连接的 SYN 报文,其 ACK 就等于“0”。所以不能简单地将“是否存在 ACK”理解为:存在 ACK 就是合法,不存在 ACK 就是非法。

对于不需要 ACK 标志为“1”的报文,它就不需要判断“S/A/L 的合法性”,所以相对应的处理流程,就可以跳过“2(S/A/L 是否合法)”判断点,而直接进入“3(是否存在 RST)”判断点。

对于参数错误和行为错误的报文,TCP 的处理对策一般是需要给对方回应一个报文。但是这个报文的格式及相关参数的值,又与其所接收的报文中的 ACK 标志是否为“1”有关。如果将这种区分也画在图中,那图5-54将变得更加复杂,乃至不可阅读。

鉴于以上原因,图5-54将方框“处理 NO ACK”,画成1个虚框,它并不是代表一个真正的处理过程,而是想强调:在后面的处理流程中,可能都会包含“有 ACK”和“NO ACK”两个分支,只是图形不太好表达,下文会用文字补充说明。

也就说,第1个判断点“是否存在 ACK”以及其具体的处理措施,其实是融于后面其他各个判断点及处理点中介绍。

 

2)S/L  判断点

S/L 是 Sequence Number(SEQ)、Data Length(DataLen)的缩写,指的是所接收报文的序列号和数据长度(是数据长度,不是报文长度)。TCP 对于 S/L 的判断,有两个基本原则:(1)本次所接收数据的 SEQ,与以前曾经所接收数据的 SEQ  不能重复;(2)本次所接收数据的 SEQ,不能超出接收空间(稍微有一点点特列)。具体判断方法,如表5-20所示:

 

表5-20  S/L 与 接收空间的关系

接收报文

数据长度

接收空间

判断法则

> 0

0

不能接收报文

0

0

RCV.NXT = SEG.SEQ

0

> 0

RCV.NXT <= SEG.SEQ < RCV.NXT + RCV.WND

> 0

> 0

RCV.NXT <= SEG.SEQ < RCV.NXT + RCV.WND

或者

RCV.NXT <= SEG.SEQ + SEG.LEN - 1 < RCV.NXT + RCV.WND

 

第1种情形,所接收的报文的数据长度大于0并且自己的接收空间等于0(SEG.DataLen > 0 and Rcv.WND == 0)。这种情形下,这样的报文是不能接受的。这也很好理解,接收空间为0,根本也接收不了数据。 

 

 

第2种情形的接收空间等于0但是其所接收报文的数据长度也为0(SEG.DataLen == 0 and Rcv.WND == 0)。它的意思是:固然不能接收数据,但是还是能接收“控制”报文,比如单纯的 ACK 报文、SYN 报文、FIN 报文、RST 报文等等。 

 

 

是的,对方没心情说话,你就吻她。确认过眼神,你是可以吻她的人——一定要确认过眼神,不然对方会说你耍流氓。这个眼神就是:RCV.NXT = SEG.SEQ。也就说,所接收报文的 SEQ 必须要等于接收方所期望的序列号(RCV.NXT)。

第3种情形,从接收空间的角度来说,有点“大材小用”:接收空间大于0,但是所接收的报文的数据长度仍然等于0。这有点 so easy 的感觉,^_^。不过虽然是 so easy,仍然要验证序列号:RCV.NXT <= SEG.SEQ < RCV.NXT + RCV.WND。

单纯从数学公式来看,第2种情形是第3种情形的特列(第2种情形的 RCV.WND = 0),但是实际上第3种情形隐含了一个事实:只要所发送的报文的 SEQ 在对方的接收空间内(同时报文的数据长度为0),那么就可以连续发送报文。

第4种情形,表达的是接收 TCP 数据的情形(前3种情形,都无法接收 TCP 数据)。这个情形有两个校验公式。

第(1)个公式:RCV.NXT <= SEG.SEQ < RCV.NXT + RCV.WND,它代表的含义,如图5-55所示:

 

图5-55 接收数据的第1个判断公式

 

这个公式只是限制了所接收报文的 SEQ 必须位于接收空间之内,但是并没有限制所接收报文的数据长度。也就是说,所接收报文的数据的长度,有可能大于接收空间的大小。对于这种情形 TCP 认为是可以接受的,毕竟受 MTU 的限制,一个报文的数据长度即使大于接收空间,也大不了多少,TCP 具体实现时,偷偷地给接收空间放大一点即可。这方收发双方都省事。

第(2)个公式:RCV.NXT <= SEG.SEQ + SEG.LEN - 1 < RCV.NXT + RCV.WND,它代表的含义,如图5-56所示: 

 

图5-56 接收数据的第1个判断公式

 

与第(1)个公式相反,第(2)公式恰恰只判断所接收报文的数据的结尾是否落在接收空间,至于数据的开头(SEG.SEQ)即使落在接收空间之外,也没有关系。 

 

 

对于以上所描述的4种情形,如果所接收的报文不能满足对应的判断法则,那么 TCP 会做两件事情:

(1)丢弃所接收的报文

(2)如果所接收的报文是 RST 报文,则不需要再做什么。否则,会给对方回1个报文,报文格式为:

<SEQ = SND.NXT> <ACK = RCV.NXT> <CTL = ACK>

这个报文的含义就是告诉对方:你发给我的报文,它的 SEQ 应该等于 RCV.NXT。

 

3)收到 RST 报文

TCP 收到 RST 报文的处理流程,与其当是所处的状态有关。

 

CLOSED 状态

对于处于 CLOSED 状态的 TCP 连接来说,它收到了炸弹,直接丢弃该报文,然后啥也不做。因为它原本就处于 CLOSED 状态,已经退无可退。

 

LISTEN 状态

对于处于 LISTEN 状态的 TCP 连接来说,它收到了这个炸弹,镇定自若,一笑而过,丢弃该报文,并且仍然是处于 LISTEN 状态。因为此时它还处于 LISTEN 状态,还没有建立连接,也就无所谓关闭,也就不需要关闭。就像你在街头耍酷,等着哪个美女来搭讪,此时如果有个美女对你翻白眼,你会这么办?继续耍酷呗,总不至于落荒而逃吧。 

 

耍裤

 

SYN-RECEIVED 状态

如果一个连接处于 SYN-RECEIVED 状态,并且它前一个状态是 LISTEN 状态,那么它收到 RST 报文时,也是丢弃该报文,并且回到 LISTEN 状态。如果它前一个状态不是 LISTEN 状态,那么它收到 RST 报文时,就会 Abort 该连接,并且状态转移到 CLOSED。

 

可接收数据状态

可接收数据状态,指的是:ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT。处于这些状态的 TCP 连接,是可以接收数据的。此时,如果收到 RST 报文,TCP 会中断(Abort)该连接:

(1)所有的接收、发送队列,都会被清空

(2)用户调用的 SEND、RECEIVE 接口也会被中断

(3)TCP 会给用户发送1个“connection reset”信号

(4)删除对应 TCB,TCP 连接状态变成 CLOSED

 

濒临关闭状态

濒临关闭状态,指的是:CLOSING、LAST-ACK、TIME-WAIT。处于这些状态的 TCP 连接,已经不可以接收数据,只是在等待最后的关闭。比如,处于 TIME-WAIT 状态的连接,就是在等待2个“MSL”时间——只要时间一到,就关闭连接。

处于濒临关闭状态的连接,如果收到RST 报文,那是相当于提前收到关闭连接的“指令”:直接删除对应的 TCB,状态变成 CLOSED。

 

4)S/C 判断点

S/C 是 Security/Compartment 的缩写,指的是所接收报文中的 Security/Compartment 字段的值。TCP 一般要求其所接收报文中的 S/C 与自己(TCB 内存中的字段)的值完全相同,如果不同,就给对方回以1个 RST 报文。 

 

一言不合就开炮

 

TCP 所回应的 RST 报文,与其所接收的报文中的 ACK 标志位有关:

(1) 如果所接收报文的 ACK 标志位为“0”,则 RST 报文的格式为:

<SEQ = 0> <AKN = SEG.SEQ + SEG.LEN> <CTL = RST, ACK>

(2) 如果所接收报文的 ACK 标志位为“1”,则 RST 报文的格式为:

<SEQ = SEG.ACK> <CTL = RST>

 

5)优先级判断点

如果说对于 S/C 的判断,TCP 是属于一言不合就开炮的类型,那么对于优先级,TCP 则要相对复杂不少。

(1) 如果所接收报文中,ACK 标志为1,那么报文中的优先级必须与自身的值相同,否则就回以1个 RST 报文:

<SEQ = SEG.ACK> <CTL = RST>

(2) 如果所接收报文中,ACK 标志为0,那么:

(2.1) 如果报文中的优先级与自身相同,则合法;

(2.2) 如果报文中的优先级小于自己,则合法;

(2.3) 如果报文中的优先级大于自己:

(2.3.1) 如果用户允许,则也是合法,并且将对应的 TCB 中优先级的值修改为所接收报文中的值;

(2.3.2) 如果用户不允许,则是非法——回以1个 RST 报文:

<SEQ = 0> <AKN = SEG.SEQ + SEG.LEN> <CTL = RST, ACK>

 

6)行为是否违法判断点

TCP 报文的行为,指的是报文的格式,比如报文中标志的取值( ACK = 1/0、SYN = 1/0)、报文是否包含数据等等。至于报文是否违法,与 TCP 当是的状态有关。比如,假设 TCP 处于 LISTEN 状态,我们回忆一下 TCP 连接创建的基本过程,如图5-57所示:

 

图5-57 TCP 连接创建的基本过程

 

从图5-57可以看到,处于 LISTEN 状态的 TCP,它所期望接收的报文的格式是:(1) SYN = 1、ACK = 0;(2)DataLen = 0。此时,其所接收的报文的 ACK = 1,那么 TCP 就会认为它所接收的报文的行为是“非法”。

对于非法行为的报文,TCP 或者是丢弃该报文,或者是除了丢弃报文还会给对方回1个 RST 报文。具体采取何种措施,仍然与 TCP 当时所处的状态有关。

 

7)处理合法行为的报文

跨过千山和万水,所接收的报文,既不是 RST 报文,又经过了各种判断点的考验,终于来到了这一关。

此时,TCP 一般会做几件事情:

(1)根据接收报文中的相关字段值,修正自己 TCB 中的值(TCB 的解释,请参考5.2.3、5.2.7)。

(2)如果所接收的报文中包含数据,则将该数据存储到缓存中。

(3)给对方回以 ACK 报文。

 

8)通用处理思路小结

根据前面的描述,我们将 TCP 接收到报文以后,其通用处理思路,总结为图5-58所示:

 

图5-58 TCP 通用处理思路小结

 

图5-58中的第1个判断点(是否存在 ACK),前文已经说过,它的判断及处理过程,其实是融于其他判断点和处理流程中的。

我们以表格的形式,将图5-58再阐述一遍,如表5-21所示:

 

表5-21  TCP 通用处理思路小结

判断点/处理点

判断及处理流程

S/L 判断点

针对所接收报文的 SEQ、DataLen 进行判断,如果判断报文不合格,则丢弃报文,并给给对方回以1个 ACK 报文,告知对方所发送报文的 SEQ 应该等于何值(如果所接收报文是 ACK 报文,则回报文)。

收到 RST 报文

收到 RST 报文,一般是关闭或者中断连接,但是对于 LISTEN、SYN-RECEIVED 的连接,则有所例外。

S/C 判断点

针对所接收报文中的 Security/Compartment 字段的值进行判断。如果判断报文不合格,则丢弃报文,并给给对方回以1个 RST 报文。

优先级判断点

针对所接收报文中的优先级字段的值进行判断。如果判断报文不合格,则丢弃报文,并给给对方回以1个 RST 报文。

行为是否违法

针对所接收报文中的标志字段、数据长度进行判断。如果判断报文不合格,则丢弃报文,并给给对方回以1个 RST 报文。(有的状态的 TCP 连接,不回报文)

合法行为报文

如果通过以上所有关卡,则说明报文既不是 RST 报文,而且各方面也都合法。针对此种报文,TCP 会:修正自己 TCB、存储数据(如果报文中有数据)、给对方回以1个 ACK 报文、修改(迁移)自己的状态

 

介绍了通用处理思路以后,下面我们针对具体的状态,看看 TCP 是如何处理其所接收的报文的。

 

5.2.12.3 LISTEN 状态

处于 LISTEN 状态的 TCP,它心目中苦苦等候的就是对方发送“连接创建”请求报文(SYN报文),其他报文对它来说,都是“非法报文”,如图5-59所示:

 

图5-59 LISTEN 状态期望接收的报文

 

处于 LISTEN 状态的 TCP,其收到报文时的处理流程,如图5-60所示:

 

图5-60 LISTEN 状态处理流程

 

图5-60与图5-58(通用处理思路)相比,处理顺序上有所不同,但是其基本思路还是想通的。

首先,TCP 判断其所收到的报文是否是 RST 报文。如果是 RST 报文,那么直接就将其丢弃,然后继续 LISTEN。

如果不是 RST 报文,TCP 继续检查该报文中是否包含 ACK,如果包含了 ACK,那么这个报文就是非法报文,那就丢弃该报文,并给对方回以1个 RST 报文,报文格式如下:

<SEQ = SEG.AKN> <CTL = RST>

如果没有包含 ACK,TCP 继续检查该报文是否包含 SYN,如果没有包含 SYN,那么这个报文就是非法报文,那就丢弃该报文,并给对方回以1个 RST 报文,报文格式如下:

<SEQ = 0> <CTL = RST>

其实以上两个判断(对应到图5-60中“2”和“3”),就是图5-58中所说的第6个判断点“行为是否合法”。

如果报文的行为也合法,TCP 会紧接着判断 Security/Compartment(图5-60中的“4”)、优先级(图5-60中的“5”),如果它们不合法,那么 TCP 就会丢弃该报文,并给对方回以1个 RST 报文,报文格式如下:

<SEQ = 0> <CTL = RST>

当流程来到图5-60中的第“6”步,那就说明所接收的报文是“合法”的,此时 TCP 会做如下几件事:

(1)修改自己的 TCB:RCV.NXT = (SEG.SEQ + 1)、IRS = SEG.SEQ

(2)计算出 ISS(5.2.13节会讲述如何计算 ISS)

(3)给对方发送报文,报文格式为:

<SEQ = ISS> <ACK = RCV.NXT> <CTL = SYN, ACK>

(4)继续修改自己的 TCB:SND.NXT = (ISS + 1)、SND.UNA = ISS

(5)将自己的状态迁移到 SYN-RECEIVED

 

5.2.12.4 SYN-SENT 状态

处于 SYN-SENT 状态的 TCP,它心目中苦苦等候的报文,如图5-62所示:

 

图5-62 SYN-SENT 状态期望接收的报文

 

图5-62描述了两个场景。

场景1就是典型的“三次握手”中的前两次握手:A 给 B 发送了 SYN 请求以后(此时 A 处于 SYN-SENT 状态),它期望能收到 B 的 <ACK, SYN> 报文,具体请参见5.2.1节。

场景2描述的是 A 和 B 双方同时发起 SYN 请求。也就说说,对于处于 SYN-SENT 状态的 TCP 来说,它不仅可以收到 <ACK, SYN> 报文(对应场景1),也可以收到 <SYN> 报文(对应场景2)。

无论是场景1,还是场景2,TCP 收到报文的处理流程,在上半部分都是一样的,如图5-63所示:

 

图5-63 SYN-SENT 状态接收报文的处理流程(上)

 

由于处于 SYN-SENT 状态的 TCP,它既可以收到 <ACK, SYN> 报文,也可以收到 <SYN> 报文,所以图5-62以上来就判断报文中的 ACK 是否等于1。

如果 ACK 等于1,那么 TCP 就需要判断报文中的 AKN 是否合法,判断公式是:

SND.UNA <= SEG.AKN <= SND.NXT

如果 SEG.AKN 满足此公式,那么所接收的报文就是合法的,否则就是非法的,那么其处理流程就是丢弃所接收的报文,并且给对方回以1个 RST 报文(如果所接收的报文是 RST 报文,就不给对方回报文了),报文格式是:

<SEQ = SEG.ACK> <CTL = RST>

如果所接收的报文的 AKN 合法,或者所接收的报文中的 ACK = 0,那么 TCP 就检测其所接收的报文是否是 RST 报文。如果是 RST 报文,TCP 的处理流程为:

(1)如果所接收报文的 ACK = 1,那么:给用户发送信号“error:connection reset”、丢弃报文、删除 TCB、状态转移到 CLOSED。

(2)如果所接收报文的 ACK = 0,那么:丢弃报文

如果经过了以上关卡,那么就来到了图5-62中的“5”、“6”,判断“Security/Compartment”、“优先级”是否合法,如果不合法,则给对方回以1个 RST 报文,并且丢弃所接收的报文。

如果两者都合法,那么就判断所接收报文中 SYN 是否等于1。如果 SYN 不等于1,那么根据前面的描述,这也是一个非法报文,它的处理流程是:丢弃该报文。

如果 SYN = 1,就来到了图5-62中的“8”(处理 SYN)。根据5.2.1节和5.2.4节的描述,或者根据图5-61,即使处理流程来到了步骤“8”,它也是分为两个场景,如图5-63所示:

 

图5-63 SYN-SENT 状态接收报文的处理流程(下)

 

图5-63是将图5-62中的步骤“8”做了展开,请注意图5-63与图5-62两者的起点的不同:前者是“报文合法”,后者是“收到报文”

收到报文并判断是合法以后,此时需要判断报文中的 ACK 是否等于1。ACK 等于1与否,决定了 TCP 处于图5-61所描述的哪种场景。

 

1)ACK = 1

ACK = 1,就是经典的“三次握手”中的“第二次握手”。第二次握手成功以后,TCP 会做如下几件事情:

(1)修改 TCB:RCV.NXT = SEG.SEQ + 1,IRS = SEG.SEQ,SND.UNA = SEG.AKN

(2)给对方回以1个 ACK 报文,报文格式为:

<SEQ = SND.NXT> <AKN = RCV.NXT> <CTL = ACK>

(3)将状态转移到 ESTABLISHED

 

2)ACK = 0

ACK = 0,就是“双方同时发送 SYN 请求”的场景:给对方发送 SYN 的请求后,也收到了对方 SYN 请求。TCP 会做如下几件事情:

(1)给对方回以1个 SYN/ACK 报文,报文格式为:

<SEQ = ISS> <AKN = RCV.NXT> <CTL = SYN, ACK>

(2)状态转移到 SYN-RECEIVED

 

5.2.12.5 SYN-RECEIVED 及其以后状态

SYN-RECEIVED 及其以后状态,是指 TCP 处于如下状态:SYN-RECEIVED、ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT。

处于这些状态的 TCP,收到报文时,它的处理流程如图5-64所示:

 

图5-64 SYN-RECEIVED 及其以后状态接收报文的处理流程

 

图5-64与图5-58(通用处理思路)完全相同,而且它们背后所代表的含义也完全相同。但是,与通用处理思路不同的是,这里还需要就非法报文、合法报文的处理,展开描述。

 

1)非法报文的处理

处于 SYN-RECEIVED 及其以后状态的 TCP,什么样的报文对它来说是非法的,对于非法的报文,它又该如何处理,这仍然与其状态有关,如表5-22所示:

 

表5-22  非法报文的处理

状态

非法报文

非法报文处理

SYN-RECEIVED

及其以后

SYN = 1

(1)给对端发送 RST 报文

(2)所有排队待处理的 SEND、RECEIVE 接口,都返回提示信息"connection reset"

(3)所有排队待发送或重发的数据,都清空(不再发送)

(4)给用户发送"connection reset"信号

(5)丢弃所接收的报文

(6)删除 TCB,进入 CLOSED 状态

SYN-RECEIVED

及其以后

ACK = 0

丢弃所接收的报文

CLOSE-WAIT

CLOSING

LAST-ACK

TIME-WAIT

DataLen > 0

丢弃所接收的数据

 

表5-22的第2行,从 TCP 基本思想来说,SYN-RECEIVED 及其以后的状态,其所接收的报文必须有 ACK 标志(ACK = 1),否则所接收的报文就是报文。

表5-22的第3行的含义是:处于这些状态的 TCP,其对方是不应该再发送数据了。如果所接收的报文中包含数据(DataLen > 0),那么该数据就是非法数据。

无论是非法报文还是非法数据,TCP 关于表5-22的后两行的处理,都比较温柔:仅仅是将所接受的报文(数据)做一个丢弃处理就可以了,剩下的就是保持不变,静待下一个报文的到来。

只是对于表5-22的第1行的处理,TCP 像疯了一样:关闭自己、给对方发送 RST 报文(目的是让对方也关闭)。为什么会如此疯狂,这是因为 SYN 请求背后可能隐藏着一个“可怕”的事实,如图5-65所示:

 

图5-65 SYN 报文的背后

 

图5-65中,B 在 T1 时刻,收到 A 的 SYN 请求报文以后,正常情况下,一直到双方的状态都变为 CLOSED,这中间的过程,B 都不会收到 A 发送过来的 SYN 请求报文。

但是偏偏在这个过程中,B 却收到了 A 的 SYN 报文?A 为什么会发送 SYN 报文?这是道德的沦丧还是人性的扭曲?谁知道 A 到底经历了什么?

 

 

抛开实现代码的 bug 不谈,很有可能是 A 异常重启了。重启以后,A 忘记了曾经它跟 B 所建立的 TCP 连接,并且还试图建立(新的)连接。对于 B 而言,它必须告知 A:当前它还处于它们曾经所创建的连接之中,它们之间必须要将曾经的连接了断之后,才能重新开始。这也就是表5-22的第1行的“疯狂”举动的背后含义。

表5-22所描述的非法报文的处理,可以用图5-66重新表述:

 

图5-66 非法报文的处理

 

图5-66中的“合法报文处理”,是一个虚框,这是因为其处理流程与报文的具体内容相关,也与 TCP 当时所处状态相关。下面我们就逐一讲述。

 

2)合法的单纯的 ACK 报文

前文说过,处于 SYN-RECEIVED 及其以后状态的 TCP,它所收到的报文必须包含 ACK(ACK = 1)。不过 ACK 报文,可能是单纯的 ACK 报文,也有可能叠加其他标志位(比如 FIN),也有可能叠加传输数据(即 DataLen > 0)。为了简化描述,我们将这种耦合分解,本小节只讲述“单纯的 ACK 报文”这一情形,也就是说:报文中的标志位,只有 ACK = 1,其他都等于0,并且数据长度也为0。

世界上没有无缘无故的爱,也没有无缘无故的恨,单纯的 ACK 报文,与上下文相关,如图5-67~70所示:

 

图5-67 单纯的ACK(1)

 

 

图5-68 单纯的 ACK(2)

 

 图5-69 单纯的 ACK(3)

 

 

图5-70 单纯的ACK(4)

 

图5--67~70所描述的,其实是4种典型场景,如表5-23所示:

 

表5-23  单纯 ACK 的场景及处理

图序号

场景

处理流程

5-67

“三次握手”之第3次握手

状态迁移:SYN-RECEIVED -> ESTABLISHED

5-68

“四次挥手”之第2次挥手

状态迁移:FIN-WAIT-1 -> FIN-WAIT-2

5-69

“四次挥手”之第4次挥手

状态迁移:LAST-ACK -> CLOSED

5-70

数据接收确认

下文描述

 

表5-23的前3行,以及图5-67~69,我们已经讲述了很多,这里就不再重复。

表5-23的第4行(也即图5-70),表达的是“A 给 B 发送数据以后,B 给 A 发送 ACK 报文,确认它收到了数据”这一场景。这一场景中,TCP 可以发送数据的状态不止一个(ESTABLISHED、CLOSE-WAIT),可以接收数据的状态也不止一个(ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2),所以图5-70中,将 A 和 B 的状态分别用“X、Y”表示。同时,图5-70还表明,这种场景下,TCP 的状态并不会迁移。

接收数据的确认(表5-23的第4行),与 TCP 的发送空间有关,如图5-71所示:

 

图5-71 ACK 报文的 AKN 与 TCP 的发送空间

 

图5-71中的发送空间,是接收本次报文前的发送空间。接收到本次报文以后,TCP 首先要关心的是这次所接收的 ACK 报文,是否确认了一些“已发送待确认”的数据。当然,关心归关心,具体是否能够确认,还与其所接收报文的 AKN(SEG.AKN)的值有关,如表5-24所示:

 

表5-24  ACK 报文的 AKN 与 TCP 的发送空间

SEG.AKN

说明

处理流程

SEG.AKN < SND.UNA

SEG.AKN 落在图5-71的“A”范围,那说明对方是重复确认

忽略掉这个 ACK 报文

SND.UNA < SEG.AKN <= SND.NXT

SEG.AKN 落在图5-71的“B”范围,那说明这个数据确认正是其所期望的

(1)将 SND.UNA 修改为 SEG.AKN,即:SND.UNA = SEG.AKN;

(2)将已经确认的数据,从“已发送待确认”的缓存中清除;

(3)给调用“SEND”接口的用户返回“OK”

SEG.AKN > SND.NXT

SEG.AKN 落在图5-71的“C”范围,那说明对方的确认序号出现了混乱

给对方回以1个 ACK 报文,告知自己的当前的 SEQ,报文格式为:

<SEQ = SND.NXT> <CTL = ACK>

那意思是:我当前才发送到 SND.NXT,你竟然已经确认了它后面的数据?

 

表5-24的第3行,除了解释了“SEG.AKN > SDN.NXT”时,TCP 该怎么做,同时也凑巧引出了单纯发送 ACK 报文的第5种场景,^_^

我们再回到第4种场景(数据接收确认)上来,处理完 SEG.AKN 与自己接收空间的 SND.UNA 之间的关系以后,TCP 还会修改自己的 SND.WND。仍然是如图5-71所示,只要是“SND.UNA < SEG.AKN <= SND.NXT”,就有可能需要修改自己的 SND.WND:SND.WND = SEG.WND。

但是这里强调的是“有可能需要”,而不是“绝对需要”。这是因为担心出现“先发后至”的场景,如图5-72所示:

 

图5-72 后发先至

 

图5-72中,如果“报文1”比“报文2”早到,那么 B 的 SND.WND 就会被设置为正确的值(2000)。但是,却发生了“先发后至”的情形:“报文1”比“报文2”晚到,结果造成了 B 的 SND.WND 被设置成了错误的值(1000)。为了解决这个情况,TCP 引入了两个变量:SND.WL1、SND.WL2。(SND.WL 是 SEND.Window LAST 的缩写)我们先不管 SND.WL1、SND.WL2 的含义,就把它们当作2个变量,初始值都为0。

TCP 关于 SND.WND 是否修改的判断规则,如表5-25所示:

 

表5-25  TCP 关于 SND.WND 是否修改的判断规则

序号

条件

1

SND.WL1 < SEG.SEQ

2

(SND.WL1 == SEG.SEQ) and (SND.WL2 <= SEG.ACK)

 

表5-25中的两个条件,只要有1个条件成立,那么赋值如下:

SND.WND = SEG.WND

SND.WL1 = SEG.SEQ

SND.WL2 = SEG.ACK

通过这个赋值,我们知道:TCP 的发送窗口(SND.WND)被修改了(赋值为本次接收报文中的 Window 字段的值),SND.WL1、SND.WL2 两个变量的值也被修改了。

如果我们把这个修改称为“发送窗口修改点(简称:修改点)”的话,表5-25的条件1,其实可以这样等价:

上次修改点时所接收报文的 SEQ < 本次所接收报文的 SEQ

这句话的含义就是:本次所接收报文是“新”报文,没有发生“先发后至”的情形。

同理,表5-25的条件2,也可以这样理解:

即使“上次修改点时所接收报文的 SEQ 等于本次所接收报文的 SEQ”,但是“上次修改点时所接收报文的 AKN 小于本次所接收报文的 SEQ”,所以本次所接收报文是“新”报文,没有发生“先发后至”的情形。

唉......TCP 真实考虑周全,把这样的规则,用文字表达出来,鄙人写起来累,您读起来也累。但愿我写的不是太苦涩,能您看的懂,^_^

总之吧,我们总结一下表5-23所说的第4种场景(数据接收确认):

(1)如果所接收报文的 AKN 在已发送待确认的序列号之间,那么修改发送空间的 SEND.UNA 变量:SND.UNA = SEG.AKN

(2)同时,如果这个报文确实是最“新”的,那么也修改 SND.WND、SND.WL1、SND.WL2 这3个变量:SND.WND = SEG.WND, SND.WL1 = SEG.SEQ, SND.WL2 = SEG.ACK

(3)其余细节,请参见前文描述

 

最后补充一下 RFC 793 关于 SND.WL1、SND.WL2 的解释:

SND.WL1:segment sequence number used for last window update

SND.WL2:segment acknowledgment number used for last window update

 

3)合法的 FIN 报文

RFC 793 定义了6个标志位、RFC 3168 增加了2个、RFC 3540 增加了1个,一共9个。到目前为止,我们介绍了其中4个:ACK、RST、SYN、FIN,其余的标志位需要放到后面的章节介绍。所以本小节介绍的 FIN 报文(FIN = 1),是本章所介绍的最后1个“控制”报文。

收到 FIN 报文后的处理情况,也与 TCP 当时所处的状态相关。

对于 CLOSED、LISTEN、SYN-SENT 状态的 TCP 来说,如果它收到 FIN 报文,会直接丢弃该报文,然后就不再做其他任何处理了。

对于 CLOSED 状态而言,这似乎有点矛盾,但是 RFC 793 确实是这么描述的:

If the state is CLOSED (i.e., TCB does not exist) then ......An incoming segment not containing a RST causes a RST to be sent in response.(处于 CLOSED 状态的 TCP,如果收到1个非 RST 报文,会给对方回以1个 RST 报文)

Do not process the FIN if the state is CLOSED, LISTEN or SYN-SENT since the SEG.SEQ cannot be validated; drop the segment and return.(处于 CLOSED、LISTEN、SYN-SENT 状态的 TCP,不处理 FIN 报文,直接丢弃,然后返回)

我们不纠结这个矛盾,笔者以为,处于 CLOSED 状态的 TCP,收到 FIN 报文,以上两种处理方法都可以接受。

 

对于处于 SYN-RECEIVED 及其以后状态的 TCP 来说,它所收到的合法的 FIN 报文一定会包含 ACK(ACK = 1),所以此时 TCP 首先会做出上一小节“合法的单纯的 ACK 报文”所讲述的那些处理流程,然后再来处理 FIN 本身。具体处理流程,与 TCP 当时所处状态有关,如表5-26所示:

 

表5-26  处理 FIN 报文

状态

处理流程

SYN-RECEIVED        ESTABLISHED

直接状态迁移到 CLOSE-WAIT

FIN-WAIT-1

如果它曾经的 FIN 被对方 ACK 了,那么状态迁移到 TIME-WAIT,同时开启 time-wait 定时器;否则状态迁移到 CLOSING

FIN-WAIT-2

状态迁移到 TIME-WAIT,同时开启 time-wait 定时器

CLOSE-WAIT

仍然保持 CLOSE-WAIT 状态。(潜台词就是:收到多次 FIN 报文没有关系,反正状态保持不变就可以了)

CLOSING

仍然保持 CLOSING 状态

LAST-ACK

仍然保持 LAST-ACK 状态

TIME-WAIT

仍然保持 TIME-WAIT 状态,并重新开始 2 MSL time-wait 计时

 

4)合法的数据

终于来到激动人心的时刻,开始接收数据了。TCP 如果不能接收数据,那跟咸鱼有什么区别?

前文说过,处于 CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT 状态的 TCP,不应该能收到数据(不是本方不能接收数据,而是对方不应该发送数据),所以此时 TCP 如果收到的报文中包含数据,它会忽略这些数据。

处于 ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2 状态的 TCP,则可以接收数据,只要承载这些数据的报文,经过了前面层层的检验。

承载合法数据的报文,可能会包含 ACK(ACK = 1),所以此时 TCP 首先会做出上一小节“合法的单纯的 ACK 报文”所讲述的那些处理流程,然后再来处理数据本身。

经过了那么多铺垫,TCP 处理所接收的数据,就变得比较简单了:

(1)将数据传递(deliver)给用户缓存

(2)修改 TCB:

(A)RCV.NXT = SEG.SEQ + SEG.DataLen,

(B)RCV.WND = RCV.WND(数据已经传递到用户缓存)or RCV.WND = RCV.WND - SEG.DataLen(数据尚未传递到用户缓存)

(3)给对方回以 ACK 报文,报文格式为:

<SEQ = SND.NXT> <AKN = RCV.NXT, WND = RCV.WND> <CTL = ACK>

告别官方WebRTC的30G编译:我用libdatachannel给USB摄像头做了个轻量级网页监控 本文介绍了一种基于libdatachannel的轻量级WebRTC监控方案,通过USB摄像头实现实时视频推流。相比官方WebRTC库30GB的庞大编译体积,libdatachannel仅需几十MB,大幅简化了开发流程。文章详细讲解了从视频采集、FFmpeg编码到WebRTC传输的全过程,并提供了性能优化和部署方案,帮助开发者快速构建高效的网页监控系统。 阅读详情

相关推荐

从AI画稿到3D虚拟时装:Illustrator与Substance 3D的服装设计工作流

本文旨在解决传统服装与纺织品设计师在产品开发流程中,面临的“2D印花图案无法直观预见3D上身效果”、“物理打样成本高昂且周期漫长”的核心痛点。我们将介绍一套纯数字化的3D可视化工作流,核心是利用 Adobe Illustrator 进行矢量印花图案创作,通过 Adobe Substance 3D Sampler 将其转化为逼真的PBR(基于物理渲染)布料材质,并最终在 Adobe Substance 3D Stager 中,将该材质应用于3D服装模型,渲染出照片级的虚拟样衣。本指南将帮助设计师以极低的成本和

Kingsdesigner的博客 1394

从可靠性的角度理解tcp

可靠性是 tcp 最大的特点。常见的用户层协议,比如 http, ftp, ssh, telnet 均是使用的 tcp 协议。可靠性,即从用户的角度来看是可靠的,只要用户调用系统调用返回成功之后,tcp 协议栈保证将报文发送到对端。引起不可靠的表现主要有两个方面,丢包和乱序。对于 tcp 来说,即使报文在传输过程中出现了丢包或者乱序,tcp 协议也能通过重传、排序等方式解决这些问题。(1)丢包丢包的原因,比如链路上有一个节点(比如路由器, 交换机或服务器)的网卡接收缓冲区满,会导致丢包;

weixin_38184628的博客 1886

【C#】控制设备管理器中设备的启用/禁用_20220506

通过C#代码实现设备管理器的启用/停止 引入Manamger程序集,查找到所需设备,控制启停

weixin_45475139的博客 4526

网络计算机

强缓存指的是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存。如果 HTTP 响应头部同时有 Cache-Control 和 Expires 字段的话,Cache-Control 的优先级高于 Expires。Cache-control 选项更多一些,设置更加精细,所以建议使用 Cache-Control 来实现强缓存。当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control,Cache-Control 中设置了过期时间大小;

AGangyaa的博客 1141

深入解析Zynq Ultrascale+ RF Data Converter中的PLL配置与时钟管理

本文深入解析了Zynq Ultrascale+ RF Data Converter中PLL配置与时钟管理的核心原理与实践。文章将RFDC时钟系统比作交响乐团,详细阐述了PLL作为指挥的关键作用,以及系统时钟、Tile时钟、参考时钟与采样时钟的层级关系。重点剖析了PLL配置参数(如VCO频率、分频器设置)的计算方法与稳定性考量,并提供了从IP配置使能顺序到多Tile同步、DRP访问等常见问题的实战避坑指南与调试技巧,帮助工程师构建稳定的射频信号处理基石。

7up55的博客 449

【SPI-NAND】Linux驱动移植实战:从规格书解析到内核适配

本文详细解析了SPI-NAND Flash的Linux驱动移植实战,从规格书关键参数提取到内核MTD子系统适配。内容涵盖存储结构解析、命令集映射、设备树配置及厂商驱动开发,特别强调ECC校验、坏块管理等NAND特性处理,并提供了性能优化与测试验证的实用技巧。

weixin_27076351的博客 350

传输控制协议(Transmission Control Protocol, TCP)

  传输控制协议(Transmission Control Protocol, TCP) TCP 协议主为了在主机间实现高可靠性的包交换传输协议。本文将描述协议标准和实现的一些方法。因为计算机网络在现代社会中已经是不可缺少的了,TCP协议

pqw1157的专栏 1684

AutoDL跑yolo

由于博主在AutoDL的JupyterLab的终端直接上传ZIp文件要么老是再上传中被中断,要么就是上传后使用unzip指令解压显示“找不到”,作为纯小白的我实在太难了!这个文件列出了一个 Python 项目所需的所有依赖包及其精确的版本号。这个文件是 Python 项目中常见的一种方式,用于确保项目在不同环境中都能以相同的依赖包配置运行。3.进入JupyterLab,在文件夹目录中找到上传的文件夹,右键点击“复制路径”。然后在终端中输入以下指令进行切换到该文件夹路径。9.安装成功后开始输入指令开跑!

m0_73804659的博客 1203

你还在为-TCP-重传、滑动窗口、流量控制

程序是如何表示发送方的四个部分的呢?TCP 滑动窗口方案使用三个指针来跟踪在四个传输类别中的每一个类别中的字节。其中两个指针是绝对指针(指特定的序列号),一个是相对指针(需要做偏移)。SND.WND:表示发送窗口的大小(大小是由接收方指定的);SND.UNA:是一个绝对指针,它指向的是已发送但未收到确认的第一个字节的序列号,也就是 #2 的第一个字节。SND.NXT:也是一个绝对指针,它指向未发送但可发送范围的第一个字节的序列号,也就是 #3 的第一个字节。指向 #4 的第一个字节是个相对指针,它需要。

weixin_58085973的博客 564

[低代码 + AI] 明道云与 Dify 的三种融合实践方式详解

融合方式技术路径优点局限或注意事项UI 嵌入iframe 表单嵌入快速集成、用户体验一致无法自定义交互逻辑明道云调用 DifyAPI 请求节点工作流自动化、逻辑灵活有 timeout 限制、需优化 promptDify 调用明道云插件或 API 调用节点可查询实际业务数据、增强 AI 智能需理解明道云 API 结构、权限设置复杂明道云与 Dify 的结合为低代码平台注入了智能动力。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 1185

图解目标检测 之 YOLO 算法 最全原理详解

YOLO 一.背景 YOLO(You Only Look Once: Unified, Real-Time Object Detection),是Joseph Redmon和Ali Farhadi等人于2015年提出的基于单个神经网络的目标检测系统。在2017年CVPR上,Joseph Redmon和Ali Farhadi又发表的YOLO 2,进一步提高了检测的精度和速度。 二.YOLO算法的网...

DFCED的博客 26万+

TCP协议如何保证可靠性

TCP协议传输的特点主要就是面向字节流、传输可靠、面向连接。这篇博客,我们就重点讨论一下TCP协议如何确保传输的可靠性的。 确保传输可靠性的方式 TCP协议保证数据传输可靠性的方式主要有: 校验和序列号确认应答超时重传连接管理流量控制拥塞控制 校验和 计算方式:在数据传输的...

weixin_37990128的博客 1427

100天精通Python(基础篇)——第1天:Python从起源到应用的全面解析(附上Python、PyCharm、VSCode下载安装详细教程)

100天精通Python(基础篇)——第1天:Python从起源到应用的全面解析(附上Python、PyCharm、VSCode下载安装详细教程)

努力让自己发光,对的人才能迎着光而来 101万+

传输层协议TCP详解(上篇)

传输层协议TCP详解上集,干货满满!!!

小白成长之路 7122

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

传输层协议——TCP

TCP 全称为 "传输控制协议(Transmission Control Protocol"). ,这种协议是对数据的传输进行一个详细的控制;

make_day_day_up的博客 2687

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

传输层协议TCP

TCP(Transmission Control Protocol,传输控制协议)是互联网中最核心的传输层协议之一,与 IP(网际协议)共同构成了 TCP/IP 协议族的基础(通常简称 “TCP/IP”)。它提供了的通信服务,确保数据在网络中准确、有序地传输,是 HTTP、FTP、SMTP 等应用层协议的底层支撑。

2401_86449430的博客 3259

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

【Linux网络#11】: 传输层协议 TCP

这篇文章对传输层协议TCP的内容进行充分讲述,关于其三次握手、四次挥手、以及它的各种其他知识都有涉及,非常详细

island1314的博客 2793

传输层协议——TCP协议

1.TCP 是面向连接的运输层协议。应用程序在使用 TCP 协议开展通信前,必须先建立起 TCP 连接。当数据传送完毕后,还需释放已建立的 TCP 连接。2.每一条 TCP 连接仅能拥有两个端点,且每一条 TCP 连接只能是点对点的(一对一)通信模式。3.TCP 提供可靠交付服务,通过 TCP 连接传送的数据,能够实现无差错、不丢失、不重复,并且按照发送顺序到达接收端。4.TCP 支持全双工通信,允许通信双方的应用进程在任意时刻都能发送数据。

2401_83603768的博客 2524

计网传输层协议:UDP和TCP

万字详细介绍计算机网络中的传输层协议, UDP和TCP, 其中UDP较为简单, 优势是高效率; TCP相较于UDP较为复杂, 优势是可靠传输, 重点介绍TCP中的十大核心机制, 即确认应答, 超时重传, 连接管理(三次握手,四次挥手),滑动窗口, 流量控制, 拥塞控制, 延时应答, 捎带应答, 面向字节流(粘包问题), TCP下的异常情况.

trong_ 的烂笔头 6082

传输层协议——TCP/UDP连接关键技术点

tcp建立的连接安全可靠,但是排队进行,无法保证延迟性,只能保持安全性TCP(传输控制协议)是一种可靠的、面向连接的网络协议,而三次握手是TCP用于建立连接的一种过程。以下是TCP和三次握手之间的相似之处:信道建立:TCP使用三次握手过程来建立连接,发送方和接收方之间的通信必须先建立一个连接。这能够确保双方都能够正确地收发数据。双向确认:在TCP的三次握手和数据传输过程中,双方都需要发送和接收确认消息。这样可以确保每个数据包在传输时都能够被正确接收,从而保证数据的可靠性。

cppstdio的博客 2771

【网络】传输层协议-Tcp协议

传输层Tcp协议,两万字图文详细讲解Tcp报文格式、确认应答机制、超时重传机制、连接管理机制:三次握手,四次挥手、滑动窗口、流量控制、拥塞控制、延迟应答、捎带应答、面向字节流、粘包问题、Tcp异常情况处理等内容。

℉f的博客 1998

学习网络编程No.12【传输层协议之TCP】

深入理解三次握手四次挥手,TCP各种策略,setsockopt接口的使用,shutdown接口的使用场景,粘包问题的来源与解决。

狂小伍的博客 2637

传输层协议:TCP协议和UDP协议

TCP是面向连接的、可靠的进程到进程通信的协议(在传输真实数据之前先要进行连接测试(三次握手),如果测试通过才会发送真实数据,否则不会发送真实数据)TCP提供全双工服务,即数据可在同一时间双向传输TCP报文​ ①、TCP将若干字节构成一个分组,叫报文段(Segment)​ ②、TCP报文段封装在IP数据报中工作在传输层提供不可搞得网络访问无连接有限的错误检查传输性能快无数据恢复特性telnet协议:明文传输,远程管理协议。

2301_81272194的博客 2204

TCP和UDP传输层协议

TCP 是一种可靠的、面向连接的协议,适用于对数据传输可靠性要求高的场景,具有较高的延迟和开销,但能保证数据准确无误地传输。UDP 是一种无连接的、轻量级的协议,适用于实时性要求高、可以容忍丢包的场景,具有较低的延迟和开销,但不保证数据的可靠性、顺序和完整性。根据不同的应用需求,选择合适的协议可以有效提高网络通信的效率和用户体验。

qq_50847694的博客 1899

【网络编程】传输层协议——TCP协议

TCP协议

qq_66314292的博客 2289

传输层TCP协议

传输层TCP协议

Xpccccc的博客 906
上一篇: 传输层协议(4):TCP 连接(下-1)
下一篇: 传输层协议(6):TCP 连接(下-3)
废言Pro
博客等级 码龄16年 1092粉丝 142原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值