1
EthanDon 2021-09-08 19:00:44 +08:00
计算机网络的协议是分层的,首先你要搞清楚每一层解决的是什么问题,然后就能明白每层协议为什么需要。
网络中各层协议不应该简单地横向比较,因为它们的要解决的问题各不相同。 “像 http 这种其实本质就是重新规划 tcp 数据报中有效数据载体部分空间是吗?” 这个说法太奇怪了,HTTP 不是来「重新规划」 TCP 报文数据的,TCP 只是载体,没有 HTTP 也就没有 TCP 的内容,何来 HTTP 来规划 TCP 数据的说法呢? |
2
EthanDon 2021-09-08 19:04:12 +08:00
实际上网络协议的上层是利用下层来屏蔽了一些细节问题,比如 HTTP 不需要再关心“网络连接”的问题,只需要专注应用数据的交付; TCP 不需要再关注 IP 寻址与路由的问题,只需要关注链接的通信;所以 HTTP 根本不关心 TCP 原来的数据是怎么样的,而 HTTP 是利用 TCP 去交付自己的数据。
不过的确,协议层数越多,报文效率越低。 |
3
yin1999 2021-09-08 19:09:36 +08:00 via Android
其实图里的理解不太对,TCP 的数据报虽然是有边界的,但是它对于上层协议表现出来的是无边界的数据流,HTTP 协议需要定义数据边界等,才能通过 TCP 正常传输数据包
|
4
felixcode 2021-09-08 19:15:58 +08:00 via Android
http,ssl 所需交互的信息都存在 tcp 数据报的载荷(payload)里,所以上层与下层协议都只关心自己的那部分。
|
5
yezheyu OP @yin1999 这个我知道,就是 TCP 滑动窗口传输那部分和粘包的问题,忘了加上这一条,我这里并不是特指 http,只是拿 http 来举例,像 IPsec 之类协议
|
6
wangxn 2021-09-08 19:38:11 +08:00
一个 TCP 包不一定能放得下整个 HTTP 请求或回应,所以不会每个 TCP 包都会有 HTTP 头,它包含的可能是其中的一个片段。
|
7
cwek 2021-09-08 20:24:32 +08:00
只是分层原理而已。你喜欢的话将语义(包括加密)、会话一次过塞到 IP 包里,用 IP 号区分协议,像 OSPF 、GRE 等。只是……IP 号不够分罢了(狗头)
|
8
xarthur 2021-09-08 20:29:38 +08:00 via iPhone
当楼主说出「粘包」这个词的时候……
|
9
guyeu 2021-09-08 20:36:40 +08:00
每一层都有开销,是这样的
|
10
ruxuan1306 2021-09-08 21:58:50 +08:00
想想寄快递,快递员根本不需要知道你怎么规划快递箱里的空间,他只需要统一封箱贴单,这个单就是协议头。
|
11
ruxuan1306 2021-09-08 22:09:54 +08:00
你不需要知道你的快递需要走哪个转运中心走哪条路又由谁送到你家,快递公司屏蔽了这些细节,在你看来,通过快递这个协议,你和收件人之间建立了点对点的货物通路。
快递公司只关心快递的重量和大小,所以你可以自己实现应用层的加密,比如你要寄些绝密文件,为了提升安全性,你可以先把它装进密码箱,然后用普通快递邮寄,再通过其它什么方式将密码告诉收件人。 |
12
gBurnX 2021-09-08 22:14:13 +08:00
Q: http 这种其实本质就是重新规划 tcp 数据报中有效数据载体部分空间是吗?
A:不是重新规划,而是 tcp / udp 这一层协议,承载了 http 数据。 =========== fix:tcp 数据报这种说法有问题。 tcp 是流,udp 才是数据报。 也有可能是你本来想说 tcp 数据包,输入错了,输成了 tcp 数据报。 =========== 把你的图改成套娃结构就对了(为了理解,只是粗略解释,并不精确): 数据帧 = 帧头 + 帧数据。 当帧数据为 IP 数据包时,IP 数据包 = IP 包头 + IP 数据。 当 IP 数据为 TCP 数据包时,TCP 数据包 = TCP 数据包包头 + TCP 数据。 当 TCP 数据为 TLS/SSL 数据包时,这里要分情况处理。 当 Client 与 Server 在加密初期(握手阶段)时,TLS/SSL 数据包是一些交互数据、证书、秘钥等用于建立加密通道的信息。 当 Client 与 Server 在加密通信阶段时,TLS/SSL 数据包 = 基于 TLS/SSL 建立好的加密通道,所承载的 HTTP 数据包。说人话,此时 TLS/SSL 数据包 = 乱码。或者说 TLS/SSL 数据包 = encrypt( httpDataPackage )。 HTTP 数据包 = HTTP Head + HTTP body 。根据通信方式,HTTP 数据包还有客户端请求数据 client request data 与服务端响应数据 server response data 的区别。 |
13
secondwtq 2021-09-08 22:33:42 +08:00
又看到这个熟悉的问题了,马克一下,今天的 V 站就刷到这里(
|
14
hxndg 2021-09-08 22:54:54 +08:00
这只能说是一部分原因吧,重点是数据的传递。
|
15
chendy 2021-09-09 00:16:04 +08:00
> 我想请问下,像 http 这种其实本质就是重新规划 tcp 数据报中有效数据载体部分空间是吗?
不是,HTTP 只管把数据交给 TCP,或者拿 TCP 收到的数据,至于 TCP 到底怎么收发数据,HTTP 管不着 |
16
lqw3030 2021-09-09 08:48:08 +08:00
从链路层到应用层,本质就是拼乐高积木,底层无法感知上层
|
17
SmiteChow 2021-09-09 09:13:04 +08:00
不对
|
18
huangmingyou 2021-09-09 09:39:28 +08:00
有效载荷是底层考虑的问题。上层协议不关心。同样,底层协议也不关心数据是啥。每层只是负责把本层的工作做好而已。
|
19
zjj19950716 2021-09-09 10:33:32 +08:00
拆快递,包装了十几层,拆到最后是一张好评返现小卡片。
|
20
labulaka521 2021-09-09 10:46:39 +08:00
做好本职工作
|
21
stach 2021-09-09 11:26:51 +08:00
lz 说的大体都是对的, 不过描述的方式很容易让人误解, 上来就给你一个 `否定`
> 我想请问下,像 http 这种其实本质就是重新规划 tcp 数据报中有效数据载体部分空间是吗? 是的 - tcp 报文的有效数据载体部分, 存储的就是 http 报文的所有内容, 包括 header 和 body > 把数据部分重新划分出一部分空间用于存储 http 协议所需的字段 https 就是在去除 http 协议所需空间,再在数据部分划分出一段用于存储 ssl 协议字段是吗?(不考虑数据加密,压缩等问题) 描述有点乱 - https 协议相当于利用现有的 http 协议层(应用层, tcp 有效数据载体部分), 又插入了一层 ssl, 介于 tcp 和 http 中间, 不属于 OSI 模型定义的网络模型, 可能是个临时过渡方案 > 所以网络传输中,协议越复杂,传输的有效数据就越少对吗? 是的 - 协议越复杂, 包裹的层数越多, 需要网络交互次数越多, 有效数据越少 > 各种协议就是对数据部分改造对吗? 是的 - 每一层协议都是在底层协议的数据部分进行改造 - 有了底层的协议作为地基, 上层协议才可以层层盖楼, 利用下一层的数据部分进行划分 |
22
2i2Re2PLMaDnghL 2021-09-09 12:41:07 +08:00
HTTPS 是 HTTP over SSL/TLS,没有去除 http 协议。就好比你为了用密码盒装信,你想必不会这么操作:
1. 把信装进信封 2. 把信从信封里拿出来 3. 把信放进密码盒 4. 把密码盒放进信封 你可以直接执行 3 、4 。 1 和 2 是多此一举。 不是「重新规划」,而只是「规划」(或者说首次规划),因为 TCP 根本没规划载荷的组织形式。你不能重新干一件没有被干过的事。 就好像说有一片自人类历史到目前都一直无主的空地,比如火星,你不能说「重新规划」火星用于太阳能发电,你只能说「规划」火星用于太阳能发电。 是的,协议层越复杂,有效载荷比例越少。但这并不必然意味着效率低。你寄信要把信塞进信封,不意味着信封降低了寄信效率;比起把信复印 70 亿份然后投递给地球上所有人,反而是显著提高了寄信效率。当然,类似信封的「重」协议和类似明信片的「轻」协议有具体开销量的区别,但同样也会有其他方面取舍。 同样地,因为数据部分本来就没什么规则,所以不能称对数据部分「改造」,是对数据部分进行「组织」。 |
23
GeruzoniAnsasu 2021-09-09 12:55:43 +08:00
> 本质就是重新规划 tcp 数据报中有效数据载体部分空间是吗
你概念中的那个「载体空间」,是不固定大小的,并不是往一个固定盒子里填更复杂的数据,而是把复杂的数据拿一个更大的盒子装,并且套上更多层 |
24
smyle 2021-09-09 13:18:02 +08:00
说法虽然有点奇怪,但也算正确,拿常见的以太网来说
IP 层的包就是以太包中的“数据”部分 传输层(也就是 tcp,udp,还有其他协议,但普通人不太会接触到)的包就是 IP 包中的”数据“部分 类似的,HTTP 、ftp 包就是 tcp 包中的”数据“部分 |
25
yezheyu OP @GeruzoniAnsasu 那也就是说套用的协议越多,在网络传输中的数据包就越大是吗?那丢失重传岂不是代价很大?
如果因为数据包太大需要重新分割的话,每段数据不都还是要加上所有协议字段,不还是很大(毕竟数据包过大就是因为协议字段过多导致的) |
26
libook 2021-09-09 18:46:51 +08:00
网络协议的本质就包的嵌套,一层包套一层包,每一层都有自己的元数据和载荷数据。
TCP 这一层,有 TCP 自己的元数据,告诉你这是个 TCP 包,来源和目标的 IP 、端口,以及长度之类的信息,对这一层来说,载荷就只是一坨数据而已,没有特殊意义; TLS 这一层,就是 TCP 的那坨载荷,有 TLS 自己的元数据,告诉你这是个 TLS 包,还有协议版本、目的地域、加密算法名称啥的,对于这一层来说,载荷就只是一坨数据而已,没有特殊意义; HTTP 这一层,就是 TLS 的那坨载荷,有 HTTP 自己的元数据( header ),载荷就是你实际传输的 body 之类的。 不要混着看,因为比如路由器在处理 TCP 数据包的时候压根不会关心载荷里是啥东西,它只关心元数据,并把载荷原样传给目的地设备; 浏览器的 TLS 程序也只关心 TLS 本身的元数据,顶多会对载荷进行解密,然后把解密后的数据给浏览器的 HTTP 程序。 |
27
libook 2021-09-09 18:52:35 +08:00
@yezheyu #25 总体数据量会变多,但是有些协议可以分割数据包,使得单个包的大小维持在一个尺寸,但包的数量增多了;也有的协议会有一些压缩方案,使得整体传输的数据量不会多出太多。
分割数据包可以不考虑数据包的结构,可以简单粗暴把整个数据包的数据切成几份,然后新加一层给每一份重新包一个数据包,到目的地后拆包直接拼起来就是原来那个数据包了。 当然实际上各种协议有自己的奇淫技巧来解决各种问题。 |
28
GeruzoniAnsasu 2021-09-09 21:19:14 +08:00
@yezheyu 套用的协议层越多,「至少需要的」数据包大小就会越大。
但当一个 2 层套 3 层套 4 层“数据包” 超过「最大盒子大小」( MTU/MSS ),就会在各协议层重组,分成更小的 fragment/frame,并给每个上层内容重新套一个本层的包头 比如 MTU 是 1K,你尝试发一个 1K 的网页,首先 HTTP 会套上 HTTP 头,写上 content-length: 1k,这样整个报文就超过 1k 了 轮到 TCP 层,它感觉一个分片发不完,分成了两个片,一片内容 1k,套上 TCP 头交给链路层,另一片内容比如 100b,套上另一个 TCP 头交给链路层。如果这两个片发出去顺序不对或者丢了一部分,TCP 负责重排重发保证接收完整 链路层,发现第一个片原本 1k 套上 TCP 头又超了 1k,于是划分帧的时候也劈两半,各自套上帧头,然后交给网卡 不过呢,TCP 协议栈在不同 OS 甚至硬件的实现上是有差异的,按照上面的假设一个 1k 内容的东西被劈成了 3 份显然不太科学。所以比如 linux 的协议栈就不像上面说的每层都自己处理一次,而是 23 层在同一块内存处理,一次性分拆好。4 层应用层一般内核就不会越界去管了,但并没有不准在内核实现 HTTP 协议做一个 234 层一起分片的协议栈。 |
29
GeruzoniAnsasu 2021-09-09 21:26:55 +08:00
@yezheyu 就是因为如果不限制分片 /分包的大小重传代价会很大所以才会限制最大单元。在最大范围内随便什么大小,超过范围强制拆分。
实现上需要对「频繁拆分导致包头冗余造成性能浪费」 vs 「 MTU 过大导致丢包重传压力过大使性能下降」之间进行权衡 |
30
jedihy 2021-09-10 05:23:26 +08:00
你理解稍微错了一点。不是重新分配每个包 TCP 的载体部分。你发一个 HTTP 请求,不是每个 TCP 包都有 HTTP 请求,第一个包装的下就只有第一个有。
网络里面传输的最大包大小是固定的叫 MTU 。 |