Java网络初识(4):网络数据通信的基本流程 -- 封装
文章目录
- [Java网络初识(4):网络数据通信的基本流程 -- 封装](#Java网络初识(4):网络数据通信的基本流程 -- 封装)
- 前言:
- 网络数据通信的基本流程
- [1. 封装](#1. 封装)
-
- [1.1 应用层:构建应用层数据包](#1.1 应用层:构建应用层数据包)
- [1.2 传输层:构建传输层数据包](#1.2 传输层:构建传输层数据包)
-
- TCP报头
- 拼接(TCP)报头的原因:
- [TCP报头包含的内容:源端口 和 目的端口](#TCP报头包含的内容:源端口 和 目的端口)
- [1.3 网络层:构建网络层数据包](#1.3 网络层:构建网络层数据包)
-
- [IP报头包含的内容:源IP 和 目的IP](#IP报头包含的内容:源IP 和 目的IP)
- [<font color = red>补充:协议类型所存放的位置:](#补充:协议类型所存放的位置:)
- [1.4 数据链路层:构建数据链路层数据帧(包)](#1.4 数据链路层:构建数据链路层数据帧(包))
- [<font color = red>补充: 关于网络传输的基本数据单位](#补充: 关于网络传输的基本数据单位)
- [1.5 物理层:硬件设备(网卡)发送数据](#1.5 物理层:硬件设备(网卡)发送数据)
- 封装的总结
- [2. 分用的介绍](#2. 分用的介绍)
- [3. 总结](#3. 总结)
前言:
如果你是第一次点击这篇博客,并且有兴趣继续往下看的话:
- 你如果对网络并不是很懂,推荐你看完我这篇博客,再继续看这篇博客:
Java网络初识(3):协议分层(TCP/IP五层模型) - 如果你有网络有一定的了解,可以直接看
网络数据通信的基本流程
网络数据通信的基本流程 ,是我们理解网络工作原理的基本盘,最核心的一个部分。
这个基本流程,比较复杂,这里通过一个例子来讲。
比如:我通过 qq,发送 hello 给对方。那么,站在网络协议的角度,是怎么完成的?
1. 封装
1.1 应用层:构建应用层数据包
应用程序,获取 到用户输入的内容 ,根据输入的内容,构建 一个应用层的数据包。这个数据包,就会把我们要发送的数据包含在里面。
构造应用层数据包的过程,就会遵守应用层协议 ,应用层协议比较特别,往往是开发这个程序的程序员自己定义的。
用微信发消息,用qq发消息,用飞书发消息,或者是钉钉,虽然都是发消息,但是,每个应用构建应用数据包的过程,采用的应用层协议都是有差异的,是开发这个程序的程序员自己定义的一套应用层协议。
qq发消息,此处假设 是这样的协议格式(约定的格式):
发送者的qq号,接收者的qq号,消息的时间,消息的正文
这里使用 ' , ' 进行分隔,形成一个字符串。
用这么一个数据包,来作为一个示例:
123456(发送者的QQ号),654321(接收者的QQ号),2025-04-16 12:00:00(消息的时间),hello(消息正文)
注意:这个数据包 ,是个很简易 的数据包,真实情况,比这个复杂很多!!!
假设,应用层数据包构建完毕之后,长成这样。
网络传输数据的本质
这里还需要知道:网络传输的数据,其实本质上,都是 "字符串 " 或者 "二进制的bit流 "。
如果你发的全是文本,那它就是"字符串"
如果你发的是二进制文件 ,那它就是 "二进制的bit流" 。
其实,文件的本质就是 二进制的bit流 ,也就是二进制文件,因为有了编码集 (码表),能够将二进制数据转化为有意义的文字语言1,才有了 字符串,也就是文本文件的说法。
其实,如果没有现在的码表,那么网络传输数据的本质就是 "二进制的bit流" ,就是 0101 这样的二进制数据。
那么,看到这的同学,肯定会有疑问:那我传输的是 0101 这样的二进制数据,那网线这类的硬件设备,是怎么传输这样的二进制数据呢?
那么,硬件设备,会有自己的方式,进行传输:
网线 :传输的是电信号 ,通过高低电平表示 01
光纤 :传输的是光信号 ,通过高频光/低频光 表示 01
WiFi :传输的是电磁波信号 (本质上还是光信号),通过高低频电磁波 表示01
所以,无论是通过那种介质传播信息,网络传输数据的本质,都是 0101 这样的二进制数据
序列化和反序列化的简要介绍
像我们这里,需要传输的这个应用层数据包,往往是一个结构化的数据 ,里面包含多个属性。什么是结构化的数据?类似于C语言的结构体,Java的类,有很多的属性。
但是,要想将这个结构化的数据,发送出去,要把结构化的数据转换 成 字符串/二进制的bit流(结构化数据 ---> 字符串/二进制的bit流),接收数据的时候,把字符串/二进制的bit流 解析回 结构化数据(字符串/二进制的bit流 ---> 结构化数据)。
结构化数据 ---> 字符串/二进制的bit流 ,这种机制,称为:序列化
字符串/二进制的bit流 ---> 结构化数据 ,这种机制,称为:反序列化
这里仅是简单介绍什么是 序列化和反序列化,后面会有介绍到,在Java中,如何使用代码来实现。
为什么要进行序列化?
答:为了结构化的数据能够传输 。
举个例子:你现在买了个大件,比如:电竞椅
那么卖家发货的时候,是把整个椅子给你发过来吗?其实不是的。
整个椅子发过去,快递那边,比较难运输,太大件了,而且运输过程中,一旦磕磕碰碰一下,容易坏,买家收到了坏的椅子,商家还要赔偿买家,说不定,还得被投诉,所以要将整个椅子,拆分成一个一个的零件,再发货。
发货之前,卖家会对你买的电竞椅进行质量检测,这里检测的是整个的椅子,测试没有问题,卖家会把这整个电竞椅 拆成多个部分,多个零件 ,进行发货,这里的操作,相当于:序列化。
你收到的,不是整个椅子,而是一大堆的零件,需要你自己组装,组装成整个的电竞椅 ,这里的操作,相当于:反序列化。
整个的电竞椅,相当于:结构化的数据
拆成的一个一个的零件,相当于:字符串/二进制的bit流
可能椅子你觉得不够大件,那你上网买个床呢?
这么大的物件,它肯定是要拆开来发货的。
到这,你应该就知道了,为什么要进行序列化,才能让结构化的数据进行传输了吧。
1.2 传输层:构建传输层数据包
在 1.1 标题内容中,我们已经构建出来一个数据包 :
123456(发送者的QQ号),654321(接收者的QQ号),2025-04-16 12:00:00(消息的时间),hello(消息正文)
构建出应用层的数据包之后,应用程序(应用层 )会调用 传输层 提供的接口 (API),把数据交给传输层 ,传输层拿到数据之后,构建出"传输层数据包"。
之前在讲协议分层的时候讲过,上层 协议会调用下层协议,下层协议给上层协议提供服务。
这里所说的上层协议调用下层协议,其实是下层协议提供了一些 api,在代码中就可以使用了,传输层提供的api,叫做:socket api,这个后面的博客会讲。
涉及到的博客,如下:
Java网络编程:(使用 socket 进行网络编程前的预备知识)
Java网络编程:(socket API编程:UDP协议的 socket API -- 回显程序)
Java网络编程:(socket API编程:TCP协议的 socket API -- 回显程序)
TCP报头
传输层的协议 ,主要是两个:TCP 和 UDP ,下面,我们假设传输层使用的是TCP协议。
那么,传输层会给应用层数据包,拼接上一个 TCP报头 。
此时,这里就构成了一段 TCP数据包 。
TCP报头 :包含TCP功能相关的属性
TCP载荷 :就是应用层数据包
拼接(TCP)报头的原因:
为什么要拼接上一个 TCP报头?
举一个例子,解释为什么要拼接上一个 TCP报头:
比如你上网买一件衣服,卖家需要发货,联系快递公司,将这件衣服送到你手里,但是,卖家并不是将这一件或多件衣服揉成一团给快递小哥的,而是会给将这些衣服包装起来。
包装之后,就可以贴快递单(标签),贴的这个快递单 ,包含了你衣服传输的关键信息 :买家网名,买家收货地址,买家的手机号码,卖家的网名,卖家的发货地址,卖家的手机号码,商品信息...
类似于我们之前学过的五元组:源IP(卖家发货地址),源端口(卖家的手机号码),目的IP(买家的收货地址),目的端口(买家的手机号码),协议类型。
有了这些关键信息,才可以支撑起接下来的传输流程 。
没有这些关键信息,就不知道该往哪里传输了。
后续的几步,也会有添加报头的步骤。
需要补充一点:TCP协议 ,本身不关心载荷内容 是什么。
只需要贴上标签,进行传输。
TCP报头包含的内容:源端口 和 目的端口
TCP报头 里包含的属性非常多,后续的博客会详细介绍。
当前阶段,你只需要知道,这里包含了 五元组中的两个:
源端口 和 目的端口
到这里,传输层数据包就构建完毕了。
1.3 网络层:构建网络层数据包
传输层 构建好数据包之后,继续调用网络层的 api ,把传输层数据包交给网络层,由网络层 这边,继续进行处理。
网络层 最主要的协议 是:IP协议
假定网络层,使用的是IP协议。
IP协议 继续对传输层的数据包进行加工,给传输层数据包拼上 IP 报头 。
IP协议 也是一样,本身不关心载荷内容是什么。
这里拼接上 IP报头 的目的 和拼接上 TCP报头 是类似的,也是为了贴标签,补充传输的信息。
IP报头包含的内容:源IP 和 目的IP
IP报头 和 TCP报头是一样的,都包含 了很多的信息,其中,有两个关键的信息 ,是五元组中的两个:
源IP 和 目的IP
补充:协议类型所存放的位置:
讲到这里,五元组 中的四个都包含在TCP报头和IP报头里面了,那么,协议类型在哪个报头中存放着呢?
答:协议类型,其实不只一份数据,协议类型存在于多个报头里面
例如:
IP报头(当前的网络层)中,就会记录当前的传输层(上一层)使用的是哪个协议。
传输层(TCP)报头 中,也会**记录应用层(传输层的上一层)**使用哪个协议。
接下来讲到的数据链路层报头中,也会记录网络层使用的是哪个协议。
... ... ...
总结来说:每一层加工后的数据包的报头中,都得记录上一层使用的是哪个协议
协议类型的存放,是分散的 。
最后的数据包,五元组的信息,肯定是会包含的。
到这里,传输层数据包就构建完毕了。
1.4 数据链路层:构建数据链路层数据帧(包)
网络层构建好数据包之后,IP协议(网络层)会继续调用数据链路层的 api ,把网络层数据包(IP数据包)交给数据链路层,由数据链路层这边,继续进行处理。
在数据链路层 中,核心的协议是:" 以太网 " 。
假设数据链路层,使用的是 " 以太网 " 这个协议。
以太网这个协议,也会在网络层数据包的基础上,进一步的加工。
这次的加工处理和前面的网络层和传输层不一样,数据链路层,不仅会添加一个以太网的报头 ,还会添加一个以太网的尾巴 。
这就是一个以太网的数据帧(包)。
大家可以看到,我这里使用了一个新的名词:数据帧 。
也在后面()中,加了一个包,为什么呢?
接下来,讲一讲网络传输的基本数据单位。
补充: 关于网络传输的基本数据单位
当我们谈到网络传输的 " 基本数据单位 " 的时候,会涉及到多个术语:
- 网络数据包,包(packet)
- 网络数据帧,帧(frame)
- 网络数据报,报(Datagram)
- 网络数据段,段(segment)
以上术语,均是网络传输数据的基本单位,但是,本篇博客或者说以后你看到我个人的博客 ,有关于网络传输的基本单位,都是用包 ,不用其他的。
原因:在企业的日常工作中 ,并不会 对这些基本数据单位,做过多的区分,只需要你知道,别人说的数据包或数据帧,都指的是网络传输的基本数据单位就可以了。
如果要严格区分,也是有区别的:
- 网络数据段:专门给 TCP协议 用的(传输层),比如:TCP数据段。
- 网络数据报:专门给 UDP协议 用的(传输层),比如:UDP数据报
- 网络数据包:专门给 IP协议 用的(网络层),比如:IP数据包
- 网络数据帧:专门给 以太网协议 用的(数据链路层),比如:以太网数据帧
到这,你应该知道,为什么我在这一个标题,使用的是 链路层数据帧(包) 了吧。
如果你看文献,或者你要考研 ,或者发表相关的论文 ,还是要严格区分这些术语的。
所以,严谨一点来说,在数据链路层构建出来的,应该叫做以太网数据帧。
讲到这里,这个数据包 ,仍然没有发送出去,需要到物理层 ,通过 硬件设备,比如网卡 ,来进行发送。
数据包的本质

讲到这,数据包已经构建完毕,我们还需要知道的是,这个数据包,实际上,他是一段二进制的数据,不是我们画出来的图,真实的数据,比这复杂的多的多的多!!!
1.5 物理层:硬件设备(网卡)发送数据
数据链路层构建好数据包之后,将完整的以太网数据包交给硬件设备(网卡),网卡会把以太网数据包(一段二进制数据),最终以 光信号/电信号/电磁波信号 传播出去 。
这里的三种不同的信号,取决于你通过什么硬件设备传输这样的二进制数据:
那么,硬件设备,会有自己的方式,进行传输:
网线:传输的是电信号,通过高低电平表示 01
光纤:传输的是光信号,通过高频光/低频光 表示 01
WiFi:传输的是电磁波信号(本质上还是光信号),通过高低频电磁波 表示01
到了这一步,数据真正的传送出去了。
封装的总结
可以看到,以qq发消息为例子,为了给某一个人发消息,过程很麻烦,但是,这样的操作,在你我看来,很复杂,很麻烦,但对于计算机来说,它一秒能处理很多这样的数据。
发送一个数据,TCP/IP五层模型中的每个层,都参与了工作 :从上层(应用层)到下层(物理层),数据在每个层都要进一步加工(添加报头),上述这个过程,就叫做:封装!
注意:这里介绍的封装 和Java语法中提到的封装 不是一个东西。
发送方,这个流程叫做封装
接收方,反过来,从下层(物理层)到上层(应用层),这个流程,叫做:分用
2. 分用的介绍
由于这篇文章,文字占据了绝大多数,如果篇幅太长,看起来会比较枯燥,所以,我将分用的介绍内容,放到了这一篇博客当中,你需要点击这个链接,观看 分用 的介绍,以及:
Java网络初识(5):网络数据通信的基本流程 -- 分用
希望能理解🙏🙏
3. 总结
封装和分用 ,是网络数据通信的基本流程,是我们理解网络工作原理的基本盘,最核心的一个部分。
希望这篇博客讲到的知识内容,能够帮助到对这方面知识有困惑的你!
如果你觉得这篇博客写得好,请你点点赞,如果有错误的讲述信息,多多指出,谢谢!