news 2026/5/12 21:29:27

linux网络相关系统调用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
linux网络相关系统调用

Linux 网络相关系统调用按功能可分为套接字创建与管理、连接建立与终止、数据收发、套接字选项与信息、I/O 多路复用、网络接口控制六大类,是用户态网络编程的核心接口。

套接字创建与基础管理

  • socket():创建通信端点(套接字),返回文件描述符。

    int socket(int domain, int type, int protocol);
    • domain:地址族(AF_INET/AF_INET6)
    • type:套接字类型(SOCK_STREAM/SOCK_DGRAM)
    • protocol:协议(0 默认)
  • socketpair():创建一对已连接的无名套接字(多用于进程间通信)。

  • close():关闭套接字,释放内核资源。

  • shutdown():单向关闭读写通道(SHUT_RD/SHUT_WR/SHUT_RDWR)。

连接建立与终止(TCP 为主)

  • bind():绑定套接字到本地地址 + 端口(服务器必用)。

    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • listen():将套接字设为被动监听模式,设置连接队列长度。

    int listen(int sockfd, int backlog);
  • accept():从监听队列接受连接,返回新通信套接字。

    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • connect():客户端发起连接请求(TCP 三次握手)。

    int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

数据收发(TCP/UDP 通用)

1. 面向连接(TCP)

  • send()/recv():基础收发,支持 flags 控制(MSG_OOB/MSG_PEEK)。

    ssize_t send(int sockfd, const void *buf, size_t len, int flags); ssize_t recv(int sockfd, void *buf, size_t len, int flags);
  • sendmsg()/recvmsg():支持分散 / 聚集 IO、控制信息(如辅助数据),功能更强大。

2. 无连接(UDP)

  • sendto()/recvfrom():收发时指定 / 获取对方地址,无需提前连接。
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

套接字选项与信息查询

  • setsockopt()/getsockopt():设置 / 获取套接字选项(超时、缓冲区大小、端口复用等)。

    int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
  • getsockname():获取套接字本地地址。

  • getpeername():获取连接对方地址。

I/O 多路复用(高并发核心)

  • select():跨平台多路复用,监听 fd 集合的读写异常事件。
  • poll():改进 select,无 fd 数量限制,效率更高。
  • epoll 系列(Linux 特有)
    • epoll_create():创建 epoll 实例。
    • epoll_ctl():注册 / 修改 / 删除监听 fd。
    • epoll_wait():等待事件触发,返回就绪 fd 列表。

网络接口与底层控制

  • ioctl():通用设备控制,常用于网卡配置(IP、子网掩码、MAC)、路由操作。
    int ioctl(int fd, unsigned long request, ...);
  • fcntl():文件控制,可设置套接字非阻塞、获取 / 设置文件状态标志。

典型流程对比

TCP 服务器

socket() → bind() → listen() → accept() → send()/recv() → close()

TCP 客户端

socket() → connect() → send()/recv() → close()

UDP 服务器 / 客户端

socket() → bind()(可选客户端)→ recvfrom()/sendto() → close()

LSM 网络基础架构

LSM(Linux Security Module)是内核安全框架,通过CONFIG_SECURITY启用,提供200 + 钩子,其中 ** 网络钩子(socket/sk_buff)** 管控全链路网络行为。

核心网络钩子(Socket 层)

拦截所有 socket 系统调用,对应网络编程核心接口:

  • socket_create:创建套接字(控制类型 / 协议族)
  • socket_bind:绑定地址 + 端口(防止特权端口滥用)
  • socket_connect:发起连接(控制目标 IP / 端口)
  • socket_listen:监听端口
  • socket_accept:接受连接
  • socket_sendmsg/socket_recvmsg:数据收发(过滤内容 / 方向)
  • socket_getsockname/getpeername:获取地址信息
  • socket_setsockopt/getsockopt:套接字选项控制

核心网络钩子(数据包层,sk_buff)

配合 Netfilter,对数据包进行标签化管控

  • netif_receive_skb:网卡收包
  • ip_local_out:IP 层发包
  • skb_security_set/get:读写数据包安全标签(SELinux/Smack 用)
  • secmark:基于 Netfilter 规则打标签(iptables 配合)

BPF‑LSM(5.7+,eBPF 动态策略)

  • 网络模型:eBPF 程序挂载 LSM 钩子,动态自定义策略
  • 核心特性:
    • 无需内核模块 / 重启,bpftool动态加载
    • 支持所有网络钩子:socket、sk_buff、Netfilter
    • 示例:阻断进程连接192.168.1.100:22、限制bind端口范围
    • 优势:可编程、动态更新、与 eBPF 生态融合
    • 局限:需 5.7+ 内核、eBPF 编程门槛
  • 典型场景:云原生、微服务、零信任安全

典型调用流程(以connect()为例)

  1. 用户态:connect(fd, addr, len)系统调用
  2. 内核态:
    • sys_connect()security_socket_connect()
    • LSM 框架遍历所有已启用模块的socket_connect钩子
    • SELinux:检查进程域(如user_t)是否允许连接目标端口类型(如ssh_port_t
    • AppArmor:检查进程 Profile 是否允许network inet tcp到目标 IP
    • BPF‑LSM:执行挂载的 eBPF 程序,动态判断放行 / 拒绝
  3. 结果:钩子返回 0 允许,-EPERM拒绝,系统调用失败

绕过系统调用

普通标准 Socket:绝对跳不过系统调用

常规socket/connect/send/recv网络程序:

  • TCP/UDP 必须走内核网络协议栈
  • 只要用内核协议栈,收发、建连、绑定端口全都要陷入内核
  • 必须触发syscall 陷入(x86int 0x80/syscall指令,ARMsvc

原因:

  1. 端口管理、路由、IP 分片、TCP 重传 / 拥塞控制全在内核
  2. 网卡硬件中断、DMA 收发只有内核能访问
  3. 资源隔离:用户态无权直接操作网卡、内核路由表

👉 标准 POSIX Socket无法跳过系统调用

绕开 Socket 系统调用:用户态收发包(跳过内核协议栈)

可以完全不用 socket 系列系统调用,直接用户态读写网卡,自己实现二层 / 三层协议。

1. 实现方案(常用 3 种)

① RAW 裸套接字(还没完全跳系统调用,但绕开协议栈)
socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
  • 仍要创建 socket 系统调用
  • 自己构造 IP/TCP 报文,内核不做协议解析、不做重组、不做重传
  • 能自由发包、伪造源 IP / 端口
② PACKET 套接字(链路层,最常用)
socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  • 直接拿到以太网帧,到 MAC 层
  • 完全绕开内核 TCP/UDP/IP 协议栈
  • 自己在用户态实现:ARP、IP、TCP、UDP
③ DPDK / AF_XDP真正大规模跳过系统调用

企业级高性能用户态网络标配:

  • 内核旁路、无系统调用、无中断、无拷贝
  • 直接用户态映射网卡 DMA 缓冲区
  • 轮询收发包,全程无 syscall 陷入
  • 自己在用户态完整实现协议栈(librte_ip、用户态 TCP 栈)

关键技术:

  • UIO / VFIO 把网卡设备直接透传给用户态
  • 内存大页、零拷贝、轮询模式替代中断
  • 彻底不调用 socket/send/recv 任何系统调用

最硬核:彻底无任何系统调用 网络通信

原理

  1. 通过mmap 映射网卡物理寄存器 / DMA 环形队列到用户态
  2. 用户态直接写网卡寄存器、填充 DMA 描述符
  3. 网卡 DMA 直接和用户态内存交互
  4. 全程一条系统调用都不执行

限制

  • 需要网卡硬件支持、驱动支持用户态映射
  • 需要 root 权限、设备权限
  • 必须自己实现二层 + 三层 + 四层协议
  • 不能和内核协议栈共存(端口冲突、路由冲突)

典型场景

  • DPDK 网关、防火墙、负载均衡
  • 金融低时延交易网络(微秒级,杜绝 syscall 陷入开销)
  • 自研私有协议栈

RAW / PACKET 涉及系统调用清单

  • RAW / AF_PACKET 不可能跳过系统调用,创建、收发、绑网卡、设选项 全依赖内核 syscall。
  • 只是绕开了内核 TCP/UDP 协议栈,但没绕开系统调用

必用

  • socket
  • sendto
  • recvfrom
  • close

高频常用

  • bind
  • setsockopt
  • getsockopt
  • ioctl
  • fcntl

进阶 / 高性能

  • sendmsg
  • recvmsg
  • mmap
  • munmap
  • bpf

RAW 套接字 / PACKET 套接字 都不需要 connect ()

TCP 是面向连接的协议:

  • connect()触发三次握手
  • 建立一条固定的<源 IP: 端口 → 目标 IP: 端口>链路
  • 之后send/recv不需要再传地址

RAW/PACKET 是无连接模式,内核不维护连接状态。

RAW 调用connect()不会建立任何连接,不会握手,不会发包。它只做一件事:

把这个 RAW socket绑定到一个固定目标 IP

之后可以直接用send()发,不用每次填地址。

connect(raw_fd, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); send(raw_fd, pkt, pkt_len, 0); // 不用目标地址了

总结:RAW 的 connect 只是简化 API,无任何网络连接行为。

PACKET 工作在以太网帧级别,没有 “连接” 概念。

Linux 虽然允许你对AF_PACKET调用connect(),但:

  • 没有任何实际网络行为
  • 不能减少系统调用
  • 不能加速发包
  • 绝大多数工具(tcpdump、抓包、注入)从不使用

为什么普通程序不这么做?

  1. 协议栈工作量巨大,要自己实现:ARP、IP 分片、TCP 三次握手、滑动窗口、重传、拥塞控制、定时器。
  2. 不兼容标准 Socket 生态
  3. 需要 root、依赖硬件、开发复杂度极高
  4. 内核协议栈已经高度优化,普通业务没必要造轮子

关键要点

  1. 标准 TCP/UDP Socket 程序必须走系统调用,无法跳过
  2. RAW/PACKET 裸包:绕开内核协议栈,但仍需少量 socket 系统调用
  3. DPDK/AF_XDP/VFIO 用户态网卡完全跳过系统调用、内核协议栈,用户态直接收发网络包
  4. 能实现,但只适合高性能网关、低时延交易、安全抓包攻防场景,不适合业务开发

总结

  • 基础通信socket/bind/listen/accept/connect/send/recv
  • 高效 IOepoll(Linux)/select/poll
  • 选项控制setsockopt/getsockopt/ioctl
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 21:25:23

2026 AI大模型接口中转站:五大平台硬核数据比拼

在2026年&#xff0c;AI工业化全面落地&#xff0c;全球AI大模型接口中转服务市场规模突破300亿美元&#xff0c;年增速达到惊人的217%。企业和开发者对服务的要求&#xff0c;从以往的“可用”提升到了极致低延迟、99.9%以上稳定性、全模型满血、合规可开票以及高并发扛量。 …

作者头像 李华
网站建设 2026/5/12 21:24:34

frameworks改变LCD分辨率,调整显示区域

480x640的屏&#xff0c;改成360x640&#xff0c;左右各去掉60像素 diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 68f4affbb..29eb360a3 100755 --…

作者头像 李华
网站建设 2026/5/12 21:22:47

车联网数据变现实战:从数据采集到商业应用的全链路解析

1. 车联网数据变现&#xff1a;从“数据是石油”到“炼油厂”的实战拆解“数据是新的石油”这句话在汽车行业喊了快十年&#xff0c;但直到最近两年&#xff0c;我们才真正看到“炼油厂”开始大规模投产并产生真金白银。作为一名在汽车电子和数据领域摸爬滚打了十几年的从业者&…

作者头像 李华
网站建设 2026/5/12 21:22:07

为AI智能体构建可编程邮箱:mailbot实战指南

1. 项目概述&#xff1a;为AI智能体打造专属的“可编程邮箱”如果你正在开发一个AI智能体&#xff0c;无论是客服机器人、自动化工作流还是个人助理&#xff0c;让它具备收发邮件的能力往往是刚需。传统的做法是什么&#xff1f;要么去折腾Gmail的API&#xff0c;忍受OAuth授权…

作者头像 李华