文章目录
-
- 一、计算机网络背景
- 二、协议
- 三、OSI七层模型
- 四、TCP/IP五层(四层)模型
-
- 1、TCP/IP概念
- 2、为什么要有TCP/IP协议
- 3、重谈协议
-
- [3.1 网络和OS的关系](#3.1 网络和OS的关系)
- [3.2 什么是协议](#3.2 什么是协议)
- 五、网络传输基本流程
- 六、跨网络传输的流程
-
- [网络中的地址管理 - 认识 IP 地址](#网络中的地址管理 - 认识 IP 地址)
- 七、Socket编程预备
从本篇文章开始,我继C++、Linux操作系统系列后将开始更新Linux网络部分的博客,希望大家能有所收获,多多支持!!
一、计算机网络背景
①独立模式:计算机之间相互独立,非常不方便
②网络互联:多台计算机连接在一起,可以完成数据共享
③局域网LAN: 计算机数量更多了, 通过交换机和路由器连接在一起
④广域网WAN: 将远隔千里的计算机都连在一起
二、协议
字面意思来看,协议表示即成的约定;
举个例子,比如上大学的你和你的父亲通电话,为了省钱则规定,铃响一声为平安,铃响两声即缺钱,铃响三声即有事,需要接通。这就是协议!
而在计算机中,计算机之间的传输媒介是光信号和电信号. 通过 "频率 " 和 "强弱 " 来表示 0 和 1 这样的 信息. 要想传递各种不同的信息, 就需要约定好双方的数据格式!
但是协议并不是制定出来一个方面就万事大吉了,计算机中要约定的事情有很多,比如计算机的生产厂商有很多,操作系统有很多,硬件设施也各有不同...如何让这些不同厂商之间生产的计算机能够相互顺畅的通信? 就需要有人站出来, 约定一个共同的标准, 大家都来遵守, 这就是网络协议 。
【需要注意的是:计算机中的协议无处不在,网络协议只是计算机众多协议的一条主线,但并不是全部】
- 网络协议分层:"纵向分层,横向分块"
好处非常明显:解耦合,可维护
三、OSI七层模型
OSI七层模型不是很常用,且十分复杂,这里先做了解:
• OSI(Open System Interconnection,开放系统互连)七层网络模型称为开放式系统互联参考模型,是一个逻辑上的定义和规范;
• 把网络从逻辑上分为了 7 层. 每一层都有相关、相对应的物理设备,比如路由器,交换机;
• OSI 七层模型是一种框架性的设计方法,其最主要的功能就是帮助不同类型的主机实现数据传输 ;
• 它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整. 通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯;
其实在网络角度,OSI 定的协议 7 层模型其实非常完善,但是在实际操作的过程中,会话层
、表示层
是不可能接入到操作系统中的,所以在工程实践中,最终落地的是 5 层协议。
------ 但是要理解上面的话,需要我们学习完网络才可以理解,这里就知道就可以。
在实际:它既复杂又不实用;,所以我们一般按照 TCP/IP 四层模型来讲解和学习。
四、TCP/IP五层(四层)模型
1、TCP/IP概念
"每一层都呼叫它的下一层所提供的网络来完成自己的请求"
先读一遍书本的定义:
• 物理层 : 负责光/电信号 的传递方式. 比如现在以太网通用的网线(双绞线)、早期以太网采用的的同轴电缆(现在主要用于有线电视)、光纤, 现在的 wifi 无线网使用电磁波等都属于物理层的概念。物理层的能力决定了最大传输速率、传输距离、抗干扰性等. 集线器(Hub)工作在物理层.
• 数据链路层: 负责设备之间的数据帧的传送
和识别
. 例如网卡设备的驱动、帧同步(就是说从网线上检测到什么信号算作新帧的开始)、冲突检测(如果检测到冲突就自动重发)、数据差错校验等工作. 有以太网、令牌环网, 无线LAN等标准. 交换机(Switch)工作在数据链路层.
• 网络层: 负责地址管理和路由选择 . 例如在IP协议中, 通过IP地址来标识一台主机, 并通过路由表的方式规划出两台主机之间的数据传输的线路(路由). 路由器(Router)工作在网路层.
• 传输层: 负责两台主机之间的数据传输 . 如传输控制协议 (TCP) , 能够确保数据可靠的从源主机发送到目标主机.
• 应用层: 负责应用程序间沟通,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等. 我们的**网络编程
主要就是针对应用层
.**

2、为什么要有TCP/IP协议

3、重谈协议
3.1 网络和OS的关系

3.2 什么是协议

- 问题:主机 B 能识别 data,并且准确提取 a=10,b=20,c=30 吗?
- 回答:答案是肯定的!因为双方都有同样的结构体类型 struct protocol。也就是说, 用同样的代码实现协议,用同样的自定义数据类型,天然就具有"共识",能够识别对方发来的数据,这不就是约定吗?
OS是C语言写的,TCP/IP也是C语言写的;
win && linux:网络代码,一定是一样的、结构体类型也是一样的! 这就是一种约定!
这也是对协议的一种朴素理解:所谓协议,就是通信双方都认识的结构化的数据类型
- 举个例子:买快递后,你收到的不只是一个物品,而是
【物品+盒子与快递单】
,这个盒子 就是对东西进行"封装 "的过程,而单子 就叫做协议报头 - 报头本质上也是一个结构体,而发货人填单子就是对该结构体实例化的过程,这里开个小头,下面会详细来说这些概念。
五、网络传输基本流程
-
两台主机,在同一个局域网下,能否直接通信?答案是可以的,原理就类似于上课,坐在一个屋子里,老师叫一个同学的名字,该同学可以听到并回答
现在的问题是,主机是如何像每个人的名字一样拥有唯一的标识来保证主机的唯一性呢?mac地址
1、认识mac地址
- MAC地址用来识别数据链路层中相连的节点
- 长度为 48 位, 即 6 个字节 一般用 16 进制数字加上冒号的形式来表示(例如:08:00:27:03:fb:19)
- 在网卡出厂时就确定了, 不能修改 mac 地址通常是唯一的(虚拟机中的 mac 地址不是真实的 mac 地址, 可能会冲突; 也有些网卡支持用户配置 mac 地址).
其实很多设备(比如生产的磁盘等硬件设备)都有自己的唯一值,我们一般叫做序列号!

在以太网环境里,为保障通信有序,遵循特定规则:任何时刻仅允许一台机器发数据,多台同时发会引发数据碰撞(即数据干扰 ),所以发数据的主机都要做碰撞检测与避免。无交换机时,整个以太网构成一个碰撞域。局域网通信中,主机靠目标MAC地址判定收到的报文是否给自己(dst)。理解这些后,可从系统角度认识局域网通信原理,进而探究同一网段内两台主机发消息的过程 。
2、同一个网段内的两台主机进行发送消息的过程
为什么非要封装一下呢? 可以自己尝试思考一下
最后整体复盘一下:
从今天开始,我们学习任何协议,都要先宏观上建立这样的认识:
- 要学习的协议,是如何做到解包的?只有明确了解包,封包也就能理解
- 要学习的协议,是如何做到将自己的有效载荷,交付给上层协议的?
六、跨网络传输的流程
网络中的地址管理 - 认识 IP 地址
IP 协议有两个版本, IPv4
和 IPv6
. 我们整个的课程, 凡是提到 IP 协议, 没有特殊说明的, 默认都是指 IPv4
• IP 地址是在 IP 协议中, 用来
标识网络中不同主机的地址
;• 对于 IPv4 来说, IP 地址是一个
4 字节
,32 位的整数
;• 我们通常也使用
"点分十进制"
的字符串表示 IP 地址, 例如192.168.0.1
; 用点分割的每一个数字表示一个字节, 范围是
0 - 255
;
通过唐僧取经 的例子深刻理解网络传输的过程
那为什么一定要交给路由器呢?
网络层,全网同一层,拿到的报文是一样的(IP地址从始至终不变)!是统一的!
【无论穿什么样的衣服,你永远是你!】
真实的数据包进行网络通信实际是这样的:
IP 网络层存在的意义:提供网络虚拟层,让世界的所有网络都是 IP 网络,屏蔽最底层网络的差异
IP 网络层(TCP/IP 模型中的网络层,对应 OSI 模型的网络层)的核心价值在于:
- 构建统一的虚拟通信平台:通过 IP 协议,将全球不同类型的底层网络(如以太网、WiFi、光纤、卫星通信等)抽象为一个逻辑上的 "IP 网络",使得无论底层是何种物理介质或技术,设备都能通过 IP 地址进行通信。
- 屏蔽底层差异:底层网络可能采用不同的帧格式、传输介质、地址体系(如 MAC 地址),但 IP 层通过封装 / 解封装机制,将这些差异隐藏在 IP 协议之下。上层应用(如 HTTP、邮件)无需关心数据是通过网线还是卫星传输,只需基于 IP 地址进行通信。
- 实现跨网络通信 :IP 协议定义了统一的编址方式(IP 地址)和路由机制,使得数据能够在不同网络之间转发,最终实现全球范围的互联互通。
简单来说,IP 网络层就像 "网络世界的翻译官",让各种 "方言不同" 的底层网络能够理解彼此,从而构建出一个全球统一的通信系统。这也是互联网能够从最初的少数网络发展到今天全球规模的关键技术基础。
七、Socket编程预备
1、源IP地址和目的IP地址
IP
在网络中,可以标识主机的唯一性
但是这里要思考一个问题:数据传输到主机是目的吗?不是的。因为数据是给人用的。
通俗的说:聊天是人在聊天,下载是人在下载,浏览网页是人在浏览但是人是怎么看到聊天信息的呢?怎么执行下载任务呢?怎么浏览网页信息呢?通过启动的 qq,迅雷,浏览器;而启动的 qq,迅雷,浏览器都是进程。换句话说,进程是人在系统中的代表,只要把数据给进程,人就相当于就拿到了数据。
所以:数据传输到主机不是目的,而是手段。到达主机内部,在交给主机内的进程,才是目的。
进程(用户) + 网络(OS)/主机 -> 网络(OS)/主机 + 进程(对端用户)
2、端口号

IP协议可以标识主机的唯一性;端口号可以标识某主机某进程的唯一性
因此:IP 地址
+ 端口号
能够标识网络上的某一台主机的某一个进程
客户端有(IP+端口),而服务器也有(IP+端口)--- 网络通信的本质:进程间通信!
(IP+端口号)即 socket
Q1:为什么有pid了还要搞端口号?不都是唯一标识进程的吗
A1:为了
解耦
!Q2:如何根据端口号分发的?
A2:进程是一个一个PCB,我们可以建立一个
hash
表,将pcb的地址和端口号一一对应!所以一个端口号只能对应一个进程
• 0~1023: 知名端口号, HTTP, FTP, SSH 等这些广为使用的应用层协议, 他们的端口号都是固定的.• 1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配的.
(OS finish后再重新理解此处 in [2h])
3、传输层的典型代表
如果我们了解了系统,也了解了网络协议栈,我们就会清楚,传输层是属于内核的,那么我们要通过网络协议栈进行通信,必定调用的是传输层提供的系统调用,来进行的网络通信。
传输层典型协议------TCP/UDP
文档对 TCP 和 UDP 协议做初步介绍,二者均为传输层协议:
- TCP:有连接、可靠传输、面向字节流
- UDP:无连接、不可靠传输、面向数据报
当前仅作基础认识,后续会深入探讨 。
4、网络字节序
我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?
网络规定:所有发送到网络上的数据,都必须是大端的!
- 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
- 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
- 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
- TCP/IP 协议规定:网络数据流应采用大端字节序,即低地址高字节.
- 不管这台主机是大端机还是小端机, 都会按照这个 TCP/IP 规定的网络字节序来发送/接收数据;
- 如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可;
因此系统内提供了一些接口,用于网络字节序和主机字节序之间的转换:
- 这些函数名很好记,
h
表示host
,n
表示network
,l
表示32 位长整数
,s
表示16 位短整数
。 - 例如 htonl 表示将 32 位的长整数从主机字节序转换为网络字节序,例如将 IP 地址转换后准备发送。
- 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
- 如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。
5、socket编程接口
c
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
// 开始监听 socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address,socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

网络基础就到这里了,后面的文章会重点放在代码操作方便啦,欢迎大家继续关注我的linux网络专栏,有更多优质文章等你来看!