【Linux】Linux内核的网络协议之socket理解
·
1. Socket(套接字) 的本质
- 它是应用程序与网络协议栈之间的编程接口(API),用于实现网络通信。
Socket 并不是一个物理设备,而是一个抽象层 - 为应用程序提供统一的网络操作接口(如
send()、recv()、bind()、connect()等)。 - 屏蔽底层协议(TCP、UDP、IP 等)的复杂性,让开发者更专注于业务逻辑。
- 在 Linux 内核中,Socket 是一个文件描述符(File Descriptor, fd),遵循“一切皆文件”的设计哲学。
2. Socket 在网络协议栈中的位置
Linux 网络协议栈的分层如下:
+-----------------------+
| Application Layer | (e.g., HTTP, FTP, SSH)
+-----------------------+
| Socket | ← 应用程序与内核的接口
+-----------------------+
| Transport Layer | (TCP/UDP)
+-----------------------+
| Network Layer | (IP, ICMP)
+-----------------------+
| Link Layer (MAC) | (Ethernet, ARP)
+-----------------------+
| Physical Layer | (网卡驱动、硬件)
+-----------------------+
Socket 的作用就是连接“应用程序”和“传输层”(TCP/UDP)。
3. Socket 的类型
Linux 支持多种 Socket,常见的有:
| Socket 类型 | 协议 | 特点 |
|---|---|---|
| SOCK_STREAM | TCP | 可靠、面向连接、字节流传输 |
| SOCK_DGRAM | UDP | 不可靠、无连接、数据报传输 |
| SOCK_RAW | 原始 IP | 直接访问 IP 层(如 ping) |
4. Socket 的工作流程(以 TCP 为例)
服务器端(Server)
socket()– 创建一个 Socket(返回 fd)。bind()– 绑定 IP 和端口。listen()– 监听客户端连接。accept()– 接受客户端连接(返回新 fd)。read()/write()– 与客户端通信。close()– 关闭连接。
客户端(Client)
socket()– 创建 Socket。connect()– 连接服务器。write()/read()– 发送/接收数据。close()– 关闭连接。
5. Socket 在内核中的实现
Linux 内核用 struct socket 表示一个 Socket,关键数据结构:
// 表示一个 Socket(内核层面)
struct socket {
struct sock *sk; // 指向 sock(存储协议状态)
const struct proto_ops *ops; // 协议操作(TCP/UDP)
// ...
};
// 存储协议状态(TCP/UDP 连接信息)
struct sock {
struct inet_sock inet; // IP 和端口信息
struct sk_buff_head receive_queue; // 接收队列(存放数据包)
// ...
};
sk_buff(Socket Buffer):内核用这个结构管理网络数据包。proto_ops:定义协议操作(如 TCP 的connect、sendmsg等)。
6. Socket 与文件描述符(fd)的关系
- 当调用
socket()时,内核会:- 创建一个
struct socket结构。 - 分配一个文件描述符(fd),并关联到该 Socket。
- 创建一个
- 之后,应用程序可以用
read(fd, ...)、write(fd, ...)等文件操作函数进行网络通信。
示例:
int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建 TCP Socket
write(sockfd, "Hello", 5); // 发送数据(类似写文件)
close(sockfd); // 关闭 Socket(类似关闭文件)
7. 如何查看 Linux 中的 Socket?
(1)ss 命令(推荐)
ss -tulnp # 查看所有 TCP/UDP Socket
-t:TCP-u:UDP-l:监听中的 Socket-n:不解析服务名(直接显示端口号)-p:显示进程信息
(2)netstat 命令(较旧)
netstat -tulnp
(3)/proc/net/tcp 和 /proc/net/udp
cat /proc/net/tcp # 查看内核中的 TCP Socket 状态
cat /proc/net/udp # 查看 UDP Socket
8. 常见问题
Q1: Socket 和文件描述符(fd)有什么区别?
- Socket 是网络通信的抽象,属于内核对象。
- 文件描述符(fd) 是用户空间访问 Socket 的句柄(整数)。
Q2: 一个进程可以有多少个 Socket?
取决于 ulimit -n(文件描述符限制),默认通常是 1024,但可以调整。
Q3: Socket 和 TCP/UDP 是什么关系?
- Socket 是接口,TCP/UDP 是协议。
SOCK_STREAM→ TCPSOCK_DGRAM→ UDP
总结
| 概念 | 说明 |
|---|---|
| Socket | 应用程序与网络协议栈之间的接口,用文件描述符(fd)表示。 |
| TCP Socket | 可靠、面向连接(SOCK_STREAM)。 |
| UDP Socket | 不可靠、无连接(SOCK_DGRAM)。 |
| 内核实现 | 通过 struct socket 和 struct sock 管理连接状态和数据包。 |
Socket 是 Linux 网络编程的核心,理解它有助于分析网络问题(如 TIME_WAIT、CLOSE_WAIT 状态)或开发高性能服务器(如 Nginx、Redis)。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)