关于计算机网络中相关协议的一点疑问

2021-09-08 18:51:28 +08:00
 yezheyu

最近在看计算机网络相关书和视频。

其中涉及到各种网络协议,如 Http,SSl 等基于 tcp/ip 之上的协议。

我想请问下,像 http 这种其实本质就是重新规划 tcp 数据报中有效数据载体部分空间是吗?

把数据部分重新划分出一部分空间用于存储 http 协议所需的字段 https 就是在去除 http 协议所需空间,再在数据部分划分出一段用于存储 ssl 协议字段是吗?(不考虑数据加密,压缩等问题)

我理解的如下图:

所以网络传输中,协议越复杂,传输的有效数据就越少对吗?

各种协议就是对数据部分改造对吗?

3005 次点击
所在节点    程序员
30 条回复
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 模型定义的网络模型, 可能是个临时过渡方案


> 所以网络传输中,协议越复杂,传输的有效数据就越少对吗?

是的
- 协议越复杂, 包裹的层数越多, 需要网络交互次数越多, 有效数据越少



> 各种协议就是对数据部分改造对吗?

是的
- 每一层协议都是在底层协议的数据部分进行改造
- 有了底层的协议作为地基, 上层协议才可以层层盖楼, 利用下一层的数据部分进行划分
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 亿份然后投递给地球上所有人,反而是显著提高了寄信效率。当然,类似信封的「重」协议和类似明信片的「轻」协议有具体开销量的区别,但同样也会有其他方面取舍。

同样地,因为数据部分本来就没什么规则,所以不能称对数据部分「改造」,是对数据部分进行「组织」。
GeruzoniAnsasu
2021-09-09 12:55:43 +08:00
> 本质就是重新规划 tcp 数据报中有效数据载体部分空间是吗

你概念中的那个「载体空间」,是不固定大小的,并不是往一个固定盒子里填更复杂的数据,而是把复杂的数据拿一个更大的盒子装,并且套上更多层
smyle
2021-09-09 13:18:02 +08:00
说法虽然有点奇怪,但也算正确,拿常见的以太网来说
IP 层的包就是以太包中的“数据”部分
传输层(也就是 tcp,udp,还有其他协议,但普通人不太会接触到)的包就是 IP 包中的”数据“部分
类似的,HTTP 、ftp 包就是 tcp 包中的”数据“部分
yezheyu
2021-09-09 14:57:04 +08:00
@GeruzoniAnsasu 那也就是说套用的协议越多,在网络传输中的数据包就越大是吗?那丢失重传岂不是代价很大?

如果因为数据包太大需要重新分割的话,每段数据不都还是要加上所有协议字段,不还是很大(毕竟数据包过大就是因为协议字段过多导致的)
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 程序。
libook
2021-09-09 18:52:35 +08:00
@yezheyu #25 总体数据量会变多,但是有些协议可以分割数据包,使得单个包的大小维持在一个尺寸,但包的数量增多了;也有的协议会有一些压缩方案,使得整体传输的数据量不会多出太多。

分割数据包可以不考虑数据包的结构,可以简单粗暴把整个数据包的数据切成几份,然后新加一层给每一份重新包一个数据包,到目的地后拆包直接拼起来就是原来那个数据包了。

当然实际上各种协议有自己的奇淫技巧来解决各种问题。
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 层一起分片的协议栈。
GeruzoniAnsasu
2021-09-09 21:26:55 +08:00
@yezheyu 就是因为如果不限制分片 /分包的大小重传代价会很大所以才会限制最大单元。在最大范围内随便什么大小,超过范围强制拆分。

实现上需要对「频繁拆分导致包头冗余造成性能浪费」 vs 「 MTU 过大导致丢包重传压力过大使性能下降」之间进行权衡
jedihy
2021-09-10 05:23:26 +08:00
你理解稍微错了一点。不是重新分配每个包 TCP 的载体部分。你发一个 HTTP 请求,不是每个 TCP 包都有 HTTP 请求,第一个包装的下就只有第一个有。

网络里面传输的最大包大小是固定的叫 MTU 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/800692

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX