目录

Linux内核套接字以及分层模型

Linux内核套接字以及分层模型

一、套接字通信

内核开发工程师将网络部分的头文件存储到一个专门的目录include/net中,而不是存储到标准位置include/linux。

计算机之间通信是一个非常复杂的问题:

  • 如何建立物理连接?
  • 使用什么样的线缆?
  • 通信介质有那些限制和特殊的要求?
  • 如何处理传输错误的问题?
  • 如何识别计算机网络中的每一台计算机?
  • 如果两台计算机通过其他计算机连接,二者之间的数据是如何进行交换?
  • 如何查找最佳的路由?
  • 如何打包数据,使它不依赖于特定计算机的特性?

1.ISO/OSI和TCP/IP参考模型

ISO设计一种参考模型,定义组成网络的各个层,该层由7层组成,成为OSI(开放系统互联)模型如下:

https://i-blog.csdnimg.cn/direct/b3a42061ed954a608a4f13ddbd393f90.png

  • 应用层:网络服务与最终用户的接口;
  • 表示层:数据的表示、安全及压缩;格式(jpeg, ascii 等);
  • 会话层:建立、管理及终止传话;
  • 传输层:定义传输数据的协议端口,以及流控和差错校验;(数据包一旦离开网卡进入网络传输层)
  • 网络层:进行逻辑地址建立、实现不同网络之间的路由选择;
  • 数据链路层:建立逻辑连接、进行硬件地址寻址、差错检验等功能(由底层网络定义协议),将比特组合成字节进而组合成帧,用 MAC 地址访问介质,错误发现但不能纠正。

其中核心基本术语如下:

  • 数据帧(Frame):指起始点和目的点都是数据链路层的信息单元。
  • 数据包(Packet):指起始点和目的地是网络层的信息单元。
  • 数据报(Datagram):指起始点和目的地都使用无连接网络服务的网络层的信息单元。
  • 段(Segment):指起始点和目的地都是传输层的信息单元。
  • 消息(Message):指起始点和目的地都在网络层以上的信息单元(经常在应用层)。
  • 元素(Cell):指的是一种固定长度的信息,它的起始点和目的地都是数据链路层。元素通常用于异步传输模式(ATM)和交换多兆位数据服务(SMDS)网络等交换环境。
  • 数据单元(Data unit):常用的数据单元有服务数据单元(SDU)、协议数据单元(PDU)。
  • 数据帧:帧数据由两部分组成:帧头部和帧数据,帧头部包括接收方主机物理地址的定位及其它网络信息,帧数据区含有一个数据体。
  • IP 数据体由两个部分组成:数据体头部和数据体的数据区,数据体头部包括 IP 源地址和 IP 目标地址及其它信息,数据体的数据区包括用户数据协议、传输控制协议,还有数据包及其它信息。

1. 数据帧(Frame)

讲解 :数据链路层的信息单元,负责在相邻设备间传输数据,包含物理地址(如 MAC 地址)等链路层信息。

例子 :好比快递包裹在某个快递网点内部流转。包裹上贴着收件网点的地址标签(类似 MAC 地址),快递员按这个标签在网点内传递包裹,这个带标签的包裹就像数据帧。

2. 数据包(Packet)

讲解 :网络层的信息单元,关注逻辑地址(如 IP 地址),用于不同网络间的路由选择。

例子 :假设快递要从北京发往上海,快递系统根据目的地城市(类似 IP 地址)规划运输路线,这个按城市地址规划路线运输的快递包裹,就是数据包。

3. 数据报(Datagram)

讲解 :网络层无连接服务的信息单元,发送方不确认接收方是否准备好,类似 “发了就不管”。

例子 :像寄平信,写信人把信投入邮筒后,不跟踪信是否送达、是否丢失,只负责发送,这封信就像数据报。

4. 段(Segment)

讲解 :传输层的信息单元,负责拆分大数据,确保可靠传输(如 TCP 协议分段)。

例子 :传输一部 2GB 的电影时,传输层会把电影拆分成多个小段(类似拆分成多个小文件),每个小段添加传输控制信息(如编号),这些小段就是段。

5. 消息(Message)

讲解 :网络层以上(常为应用层)的信息单元,直接面向用户需求。

例子 :用微信发送一段文字 “你好”,这段文字对用户是直观的信息,应用层处理后发送,这个文字内容就是消息,用户不关心底层如何传输。

6. 元素(Cell)

讲解 :数据链路层的固定长度信息单元,用于 ATM 等交换网络(与可变帧长的传统以太网相比,ATM固定心愿长度传输更适用于实时性、稳定性要求极高的业务;但因技术复杂、成本高,逐渐被以太网等技术取代,目前更多用于特定专业领域),传输高效、规则。

例子 :像标准化的货柜,每个货柜大小、规格固定(固定长度)。在 ATM 网络中,数据像货物一样被装进这些固定规格的货柜传输,确保快速交换,这个货柜就是元素。

7. 数据单元(SDU、PDU)

  • 服务数据单元(SDU) :上层协议交给下层处理的数据,关注 “服务内容”。

    例子 :用户在网盘上传文件,文件内容就是 SDU,网盘底层协议(如 HTTP)会处理它。

  • 协议数据单元(PDU) :加入协议控制信息后的数据单元,关注 “协议处理”。

    例子 :还是上传文件,底层协议给文件添加头部信息(如传输规则、地址),组合后的整体(文件 + 头部)就是 PDU,类似给文件装个 “协议信封” 再发送。

各层执行的任务:

主机到网络层负责将信息从一台计算机传输到远程计算机。它处理传输介质的物理性质,并将数据流换分为定长的帧,以便在发生传输错误时重传数据块。假设几台电脑共享同一传输线程,网络接口卡必须有唯一一个ID号,MAC地址。

IP使用一定格式的地址来寻址计算机,比如192.168.186.138,这些地址由正式注册权威机构或提供者分配(有时为动态的)。

2.创建套接字

套接字不仅可以用于各种传输协议的IP连接,也可以用于内核支持的所有其他地址和协议类型(例如:IPX、Appletalk、本地UNIX套接字,还有在<socket.h>中列出的许多其他类型)。

https://i-blog.csdnimg.cn/direct/ee94bd5334654f9ea301acfdc515236c.png

  • sa_family:是地址家族,一般都是以 AF_XXX 形式出现,比如大多数都是用 AF_INET,代表 TCP/IP 协议中用于ipv4的地址家族。
  • Sa_data:是 14 字节协议地址。这个数据结构用做 bind, connect, recvfrom, sendto 等函数的参数,指明地址信息。

https://i-blog.csdnimg.cn/direct/a2d6f20bcf6a4454be59622d5ded7e39.png

short sin_family; // 一般是指:AF_INET 地址族 PF_INET 协议族

unsigned short sin_port;// 端口号(必须要采用网络数据格式,普通数字大家可以使用 htons () 函数转换成网络数据格式的数字)

struct in_addr sin_addr; // IP 地址 32 位

unsigned char sin_zero [8]; // 它没有实际意义,只是为了跟 sockaddr 结构在内存中对齐

https://i-blog.csdnimg.cn/direct/e9172f4c4fb04567bf276fcee4ba8eae.png

in_addr_t s_addr就是存储32位的ipv4地址,明确区分IPv4地址与其他数据,避免直接操作原始整数,并与特定API兼容(如bind、connect)。

BSD 网络软件中包含两个重要的函数:inet_addr,inet_ntoa。用来在二进制地址格式和点分十进制字符串格式之间转换,仅支持 IPv4。也有两个函数同时支持 IPv4 和 IPv6:inet_ntop, inet_pton。

3.使用套接字

简要说明套接字如何表示到内核网络子系统的接口,设计简短程序。例如简单的并发服务器模型如下图所示。在服务器端,主程序提前构建多个子进程,当客户端的请求到来的时候,系统从进程池中选取一个子进程处理客户端的连接,每个子进程处理一个客户端的请求,在全部子进程的处理能力得到满足之前,服务器的网络负载是基本不变的。

https://i-blog.csdnimg.cn/direct/cdb2c466745e46009da5c4bfc0737376.png

TCP 并发服务器,在处理客户端请求之前,程序先分叉为 3 个子进程,对应多个客户端的请求,由多个子进程进行处理。与循环服务器相比较,并发的 TCP 程序,在处理客户端请求的时候,不再简单地使用一个 while 进行客户端请求的串行处理,而是 fork () 一个进程,将客户端的请求放到一个进程中进行处理。

(1)server.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>

#define BUFFLEN 1024
#define SERVER_PORT 8888
#define BACKLOG 5
#define PIDNUMB 3
static void handle_connect(int s_s)
{	
	int s_c;	
	struct sockaddr_in from;				
	socklen_t len = sizeof(from);
	
	while(1)
	{
		s_c = accept(s_s, (struct sockaddr*)&from, &len);
		time_t now;								
		char buff[BUFFLEN];						
		int n = 0;
		memset(buff, 0, BUFFLEN);			
		n = recv(s_c, buff, BUFFLEN,0);		
		if(n > 0 && !strncmp(buff, "TIME", 4))	
		{
			memset(buff, 0, BUFFLEN);			
			now = time(NULL);					
			sprintf(buff, "%24s\r\n",ctime(&now));	
			send(s_c, buff, strlen(buff),0);	
		}		
		close(s_c);	
	}
		
}
void sig_int(int num)
{
	exit(1);	
}
int main(int argc, char *argv[])
{
	int s_s;									
	struct sockaddr_in local;					
	signal(SIGINT,sig_int);  //捕获ctrl+C,使用sig_int函数处理
	
	s_s = socket(AF_INET, SOCK_STREAM, 0);
	
	memset(&local, 0, sizeof(local));			
	local.sin_family = AF_INET;					
	local.sin_addr.s_addr = htonl(INADDR_ANY);	
	local.sin_port = htons(SERVER_PORT);		
	
	bind(s_s, (struct sockaddr*)&local, sizeof(local));
	listen(s_s, BACKLOG);				
	
	pid_t pid[PIDNUMB];
	int i =0;
	for(i=0;i<PIDNUMB;i++)
	{
		pid[i] = fork();
		if(pid[i] == 0)						
		{
			handle_connect(s_s);
		}
	}
    
	while(1);	
	close(s_s);
	
	return 0;
}

(2)client.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define BUFFLEN 1024
#define SERVER_PORT 8888
int main(int argc, char *argv[])
{
	int s;	
	struct sockaddr_in server;				
	char buff[BUFFLEN];							
	int n = 0;								
	
	
	s = socket(AF_INET, SOCK_STREAM, 0);
	

	memset(&server, 0, sizeof(server));		
	server.sin_family = AF_INET;				
	server.sin_addr.s_addr = htonl(INADDR_ANY);
	server.sin_port = htons(SERVER_PORT);			
	

	connect(s, (struct sockaddr*)&server,sizeof(server));
	memset(buff, 0, BUFFLEN);					
	strcpy(buff, "TIME");					

	send(s, buff, strlen(buff), 0);
	memset(buff, 0, BUFFLEN);					
		
	n = recv(s, buff, BUFFLEN, 0);

	if(n >0){
		printf("TIME:%s",buff);	
	}
	close(s);
	
	return 0;
}

4.数据报套接字

UDP是建立在IP连接之上的第二种广泛使用的传输协议。UDP表示User Datagram Protocal(用户数据报协议)。UDP通常用于视频会议、音频流以及类似的服务。

UDP 与 TCP 有所不同

● UDP 是面向分组的,在发送数据之前,无须建立显式的连接;

● 分组可以在传输期间丢失,不保证数据一定能够到达其目的地;

● 分组接收的次序不一定与发送的次序相同。

二、网络分层模型

1.模型

内核网络子系统的实现与刚介绍的TCP\IP参考模型非常相似。相关的C语言代码划分为不同层次,各层次都有明确定义的任务,各个层次只能通过明确定义的接口与上下文紧邻的层次通信。这种做法的好处在于,可以组合使用各种设备、传输机制和协议。

https://i-blog.csdnimg.cn/direct/8f66d07fef864e98a928917b15963dd2.png

2.历史上的协议

一、AppleTalk 协议

1. 背景与历史
  • 开发者 :Apple 公司(1985年推出)。
  • 用途 :专为早期 Macintosh 计算机 设计的局域网协议,支持文件共享、打印服务等。
  • 现状 :已被 TCP/IP 取代,现代 macOS 不再原生支持。
2. 协议组成
  • DDP(Datagram Delivery Protocol)

    • 作用 :网络层协议,提供无连接的数据报传输(类似 IP)。
    • 寻址 :使用 网络号 + 节点号 (如 Network 100, Node 5 )。
  • ATP(AppleTalk Transaction Protocol)

    • 作用 :传输层协议,提供可靠的事务处理(类似 TCP)。
    • 特点 :基于请求-响应模型,确保数据完整性。
  • 其他协议

    • ZIP(Zone Information Protocol) :管理逻辑网络分区(Zone)。
    • NBP(Name Binding Protocol) :将设备名解析为网络地址。
3. 网络拓扑
  • 物理层 :支持 LocalTalk(专用串行接口,速度 230 Kbps)、EtherTalk(基于以太网)。
  • 局限性 :低速、封闭生态,难以适应互联网时代需求。

二、IPX/SPX 协议

1. 背景与历史
  • 开发者 :Novell 公司(1980年代)。
  • 用途 :为 Novell NetWare 网络操作系统设计的核心协议。
  • 现状 :逐渐被 TCP/IP 取代,Windows 通过 NWLink 兼容 IPX/SPX。
2. 协议组成
  • IPX(Internetwork Packet Exchange)

    • 作用 :网络层协议,提供无连接的数据包路由(类似 IP)。
    • 寻址 :使用 网络号 + 节点号(MAC地址) (如 Network 0x1A2B, Node 00:1A:2B:3C:4D:5E )。
  • SPX(Sequenced Packet Exchange)

    • 作用 :传输层协议,提供面向连接的可靠传输(类似 TCP)。
    • 特点 :支持数据分段、按序传递和重传机制。
3. 优势与局限
  • 优势

    • 高效路由 :IPX 的路由协议(RIP)简单高效,适合局域网。
    • 即插即用 :节点自动获取网络号,无需手动配置。
  • 局限

    • 缺乏互联网兼容性 :IPX 地址格式与 IP 不兼容,无法直接接入互联网。
    • 协议臃肿 :SPX 的可靠性机制增加了开销。

三、SDLC 与 HDLC 协议

  • 背景 :IBM 为 SNA(Systems Network Architecture) 设计的数据链路层协议。

  • 特点

    • 同步传输 :时钟信号同步数据帧。
    • 拓扑支持 :点对点、多点(轮询机制)。
    • 帧格式 :帧头 + 数据 + CRC 校验 + 帧尾。
  • 应用场景 :早期 IBM 大型机与终端通信。

  • 背景 :基于 SDLC 改进,由 ISO 标准化(ISO 13239)。

  • 改进点

    • 协议独立性 :支持多种网络层协议。
    • 帧类型扩展 :新增监控帧(Supervisory Frame)和无编号帧(Unnumbered Frame)。
    • 多点连接优化 :支持平衡模式(两台设备平等通信)。
  • 应用场景 :广域网(如 PPP 协议基于 HDLC 设计)、路由器间通信。

3. 关键对比
特性SDLCHDLC
标准化IBM 私有协议ISO 国际标准(ISO 13239)
拓扑支持主从模式(Primary-Secondary)平衡模式(Peer-to-Peer)
帧类型仅信息帧和控制帧信息帧、监控帧、无编号帧
适用性专用于 SNA 网络通用广域网和数据链路层

四、协议在 OSI 模型中的位置

协议OSI 层级核心功能
AppleTalk网络层(DDP) 传输层(ATP)数据报传输、可靠事务处理
IPX网络层数据包路由与寻址
SPX传输层可靠连接与数据分段
SDLC/HDLC数据链路层帧同步、错误检测、流量控制

五、为何这些协议被淘汰?

  1. TCP/IP 的崛起

    • 开放性 :TCP/IP 是开放标准,跨平台兼容性强。
    • 互联网支持 :IP 地址体系天然适配全球互联网。
  2. 技术局限性

    • AppleTalk 和 IPX 的封闭生态难以扩展。
    • SDLC/HDLC 复杂度高,被更简单的 PPP、以太网取代。
  3. 硬件演进

    • 高速以太网和无线网络需要更高效的协议栈。

3.各协议层的数据划分为首部和数据

https://i-blog.csdnimg.cn/direct/7f79e8b071284e0e8b02f769cabb233a.png

首部部分包含了与数据部分有关的元数据(目标地址、长度、传输协议类型等),数据部分包含有用数据(或净荷)。传输的基本单位是帧,网卡以帧为单位发送数据。帧首部部分的主要数据项是目标系统的硬件地址,这是数据传输的目的地,通过电缆传输数据时也需要该数据项。

高层协议的数据在封闭到以太帧时,将协议产生的首部和数据元二组封装到帧的数据部分。

以太网帧中,通过 TCP/IP 传输 HTTP 数据如下:

https://i-blog.csdnimg.cn/direct/ac81f69474764052aaf77437cf250751.png