资讯动态

struct socket 详解

发布时间:2026/8/16 19:29:08 来源:尧图企业网站定制
struct socket是 Linux 内核中对BSD 套接字的抽象位于用户态与协议栈之间负责文件系统接口与通用套接字状态管理而struct sock是其底层协议实现TCP/UDP/RAW。结构体定义内核 5.x定义路径include/linux/net.hstruct socket { socket_state state; /* 套接字状态粗粒度 */ short type; /* 套接字类型SOCK_STREAM等 */ unsigned long flags; /* 标志位异步、非阻塞等 */ struct socket_wq __rcu *wq; /* 等待队列poll/epoll */ struct file *file; /* 关联的文件对象fd映射 */ struct sock *sk; /* 指向网络层sock结构核心 */ const struct proto_ops *ops; /* 协议操作函数集bind/listen等 */ };关键字段解析1.state套接字状态socket_state枚举typedef enum { SS_FREE 0, /* 未分配 */ SS_UNCONNECTED, /* 未连接 */ SS_CONNECTING, /* 连接中 */ SS_CONNECTED, /* 已连接 */ SS_DISCONNECTING /* 断开中 */ } socket_state;特点仅反映用户态可见的高层状态与 TCP 内核状态如ESTABLISHED不同步。2.type套接字类型enum sock_type { SOCK_STREAM 1, /* 流式TCP */ SOCK_DGRAM 2, /* 数据报UDP */ SOCK_RAW 3, /* 原始套接字 */ SOCK_RDM 4, /* 可靠消息 */ SOCK_SEQPACKET 5 /* 有序分组 */ };3.flags标志位位掩码SOCK_ASYNC_NOSPACE异步无空间SOCK_NONBLOCK非阻塞模式SOCK_CLOEXEC执行时关闭close-on-exec4.*file文件系统接口每个 socket 对应一个struct file实现read()/write()/close()等文件操作。fd → file → socket → sk是内核映射链路。5.*sk网络层核心struct sock关键区分struct socket用户态接口、文件抽象、通用状态。struct sock协议栈实现、连接细节、缓冲区、TCP 状态等。内核中sk-sk_socket反向指向struct socket。6.*ops协议操作函数集struct proto_opsstruct proto_ops { int (*family)(struct socket *sock); int (*bind)(struct socket *sock, struct sockaddr *umyaddr, int addrlen); int (*listen)(struct socket *sock, int backlog); int (*accept)(struct socket *sock, struct socket *newsock, int flags); int (*connect)(struct socket *sock, struct sockaddr *vaddr, int addrlen, int flags); // ... sendmsg/recvmsg/mmap等 };不同协议TCP/UDP/UNIX有各自的proto_ops实现如inet_stream_opsTCP、inet_dgram_opsUDP。与struct sock的关系struct sock远更大含缓冲区、定时器、连接四元组等struct socket仅 8 个字段轻量级顶层抽象。分层设计struct socket顶层文件系统抽象用户态直接操作。struct sock底层协议栈实现含inet_sock→tcp_sock等扩展。生命周期socket()→ 创建struct socketstruct sock。close()→ 释放struct socketstruct sock可能因TIME_WAIT延迟释放。创建流程socket()系统调用用户调用socket(domain, type, protocol)。内核sys_socket()→sock_create()分配struct socket初始化stateSS_UNCONNECTED、type。分配struct sock根据domain/type绑定协议TCP→tcp_sock。初始化socket-sk sksk-sk_socket socket。分配fd创建struct file并关联socket返回fd。struct proto_ops作用套接字统一操作接口层把bind/listen/connect/send/recv等系统调用转发到对应协议IPv4/IPv6/Unix/TCP/UDP的具体实现是socket 层 → 协议层的跳板。完整内核结构体定义Linux 5.x/6.x 通用struct proto_ops { /* 协议族 */ int family; /* 创建套接字 */ struct socket *create(struct net *net, int protocol); /* 绑定地址 */ int bind(struct socket *sock, struct sockaddr *uaddr, int addrlen); /* 监听仅流式 */ int listen(struct socket *sock, int backlog); /* 接受连接 */ int accept(struct socket *sock, struct socket *newsock, struct file *file, int flags); /* 发起连接 */ int connect(struct socket *sock, struct sockaddr *uaddr, int addrlen, int flags); /* 断开连接 */ int disconnect(struct socket *sock, int flags); /* 获取本地地址 */ int getname(struct socket *sock, struct sockaddr *uaddr, int peer); /* 关闭 */ int shutdown(struct socket *sock, int how); /* 发送消息核心 */ int sendmsg(struct socket *sock, struct msghdr *msg, size_t size); /* 接收消息核心 */ int recvmsg(struct socket *sock, struct msghdr *msg, size_t size, int flags); /* 内存映射 */ int mmap(struct file *file, struct vm_area_struct *vma); /* 轮询 poll/epoll */ __poll_t poll(struct file *file, struct socket *sock, struct poll_table_struct *wait); /* 释放 */ void release(struct socket *sock); /* 套接字控制选项 setsockopt/getsockopt */ int setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen); int getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen); /* 快速ioctl */ int ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); /* 异步通知 */ int compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); /* 校验地址合法性 */ int addr_valid(struct net *net, struct sockaddr *sa, int len); /* 重连 */ int reconnect(struct socket *sock, int flags); };核心字段逐句解释family协议族AF_INET、AF_INET6、AF_UNIX区分 IPv4/IPv6 / 本地域套接字。createsocket()系统调用最终入口分配struct sock底层协议结构。bind对应用户态bind()绑定端口 IP。listen仅 TCP 实现UDP 为空实现开启监听队列。acceptTCP 专用从半连接队列取出新连接创建新 socket。connect用户态connect()TCP 发起三次握手UDP 仅记录对端地址。sendmsg / recvmsg数据收发核心write/send/sendto最终都走sendmsgread/recv/recvfrom最终都走recvmsgpoll对接select/poll/epoll判断套接字可读 / 可写 / 异常。shutdown / releaseshutdown半关闭releaseclose()真正释放套接字资源setsockopt / getsockopt配置套接字参数超时、缓冲区大小、端口复用、TTL 等。最常用四大协议 ops 实例// TCP IPv4 extern const struct proto_ops inet_stream_ops; // UDP IPv4 extern const struct proto_ops inet_dgram_ops; // 原始套接字 extern const struct proto_ops inet_raw_ops; // Unix 本地套接字 extern const struct proto_ops unix_stream_ops; extern const struct proto_ops unix_dgram_ops;调用层级极简链路用户态 connect() ↓ sys_connect() 系统调用 ↓ sock-ops-connect() ↓ inet_stream_connect() ↓ TCP 协议栈 tcp_v4_connect()与 socket /sock 三者关系struct socket上层文件抽象给 VFS 用struct proto_ops方法函数表统一接口struct sock底层协议内核实体存缓冲区、状态、四元组一句话socket是对象proto_ops是对象的成员方法sock是对象私有数据。关键差异流式 socket (SOCK_STREAM)实现全量 opslisten/accept/connect 都有效数据报 (SOCK_DGRAM)无 listen、无 accept仅收发原始套接字绕过传输层直接操作 IP 包struct sock定位Linux 网络协议栈最核心基类结构体struct socket上层 VFS 文件层给用户态用struct sock内核协议层通用基结构体派生inet_sock→tcp_sock/udp_sock/raw_sock整体层级关系struct socket ↓ sk指针 struct sock // 通用套接字基类 ↓ 内嵌 struct inet_sock // IPv4通用扩展 ↓ 继承 struct tcp_sock // TCP专属 struct udp_sock // UDP专属精简版 struct sock 核心源码Linux 5.4~6.8struct sock { /* 网络命名空间 */ struct net *sk_net; /* 套接字状态、类型、协议族 */ __sk_state sk_state; // TCP状态机 short sk_type; // SOCK_STREAM/DGRAM unsigned short sk_family; // AF_INET/AF_INET6 /* 绑定/连接五元组 */ __be32 sk_rcv_saddr; // 本机接收IP __be32 sk_daddr; // 目的IP __be16 sk_num; // 本机端口 __be16 sk_dport; // 目的端口 /* 读写缓冲区核心 */ struct sk_buff_head sk_receive_queue; // 接收队列 struct sk_buff_head sk_write_queue; // 发送队列 /* 等待队列、阻塞唤醒 */ wait_queue_head_t sk_wq; /* 协议操作集 */ struct proto *sk_prot; // 传输层操作表(tcp_prot/udp_prot) struct proto_ops *sk_ops; // socket层操作表 /* 超时、定时器 */ unsigned long sk_timer_expires; struct timer_list sk_timer; /* 引用计数、标志位 */ refcount_t sk_refcnt; unsigned long sk_flags; /* 反向指向上层socket */ struct socket *sk_socket; /* 阻塞/非阻塞、错误码 */ int sk_err; unsigned int sk_sndtimeo; // 发送超时 unsigned int sk_rcvtimeo; // 接收超时 /* 内存限制收发缓冲区大小 */ int sk_rcvbuf; int sk_sndbuf; /* 多线程、锁 */ spinlock_t sk_lock; /* 安全、用户态凭证 */ struct cred *sk_cred; /* 扩展私有数据 */ void *sk_user_data; };关键字段逐字精讲sk_state套接字内核 TCP 状态TCP_ESTABLISHED 已建立 TCP_SYN_SENT 已发SYN TCP_SYN_RECV 收到SYN TCP_FIN_WAIT1 主动关闭发FIN TCP_FIN_WAIT2 TCP_TIME_WAIT 超时等待 TCP_CLOSE 关闭 TCP_LISTEN 监听区别struct socket.state上层粗状态sock.sk_state内核 TCP 精确状态五元组地址信息sk_rcv_saddr本机绑定 IPsk_daddr远端目标 IPsk_num本机端口sk_dport远端端口内核路由、防火墙、NAT 全靠这组字段匹配。三大核心队列网络收发包核心sk_receive_queue内核收到数据包先放入接收队列用户recv/read从此取包sk_write_queue用户send/write数据先放入发送队列内核协议栈异步发出队列元素struct sk_buff内核网络报文结构两套函数表超级重点①sk_ops struct proto_opsSocket 层接口bind listen accept connect sendmsg recvmsg用户态系统调用走这里②sk_prot struct proto传输层协议接口TCPtcp_protUDPudp_prot包含connect/disconnect/close/recvmsg/sendmsg内核底层实现调用链路用户 send() → sys_send → socket-ops-sendmsg → sock-sk_prot-sendmsg → tcp_sendmsg / udp_sendmsg超时控制sk_sndtimeo发送阻塞超时sk_rcvtimeo接收阻塞超时setsockopt(SO_RCVTIMEO/SO_SNDTIMEO)直接修改这两个值缓冲区大小sk_rcvbuf接收缓冲区上限sk_sndbuf发送缓冲区上限对应/proc/net/ipv4/tcp_rmem / tcp_wmem生命周期sk_refcnt引用计数close 不一定立刻释放TIME_WAIT 期间依然持有 sock双向绑定socket-sk sock; sock-sk_socket socket;上下层互相指向完成 VFS ↔ 协议栈打通。sock 三层继承体系1. struct sock 通用基类所有协议共用 2. struct inet_sock IPv4 通用扩展 包含TTL、服务类型、IP选项、分片信息 3. 具体协议子类 struct tcp_sock // TCP独有拥塞窗口、序列号、重传队列、SACK、滑动窗口 struct udp_sock // UDP独有校验和、封装、分片控制容器获取写法// 由 sock 转 inet_sock struct inet_sock *inet inet_sk(sk); // 由 sock 转 tcp_sock struct tcp_sock *tp tcp_sk(sk);socket /sock/proto_ops /proto 四者终极关系struct socket面向文件系统管 fd、阻塞状态struct proto_opssocket 对外方法表struct sock网络内核实体存连接、队列、状态struct protosock 底层传输层实现一句话socket 是门面sock 是真身ops 是对外接口proto 是内核实现。整体层级链路从上到下用户态 fd 文件描述符 ↓ 【struct socket】 // VFS 文件层面向用户 ↓ ops 函数表 【struct proto_ops】// Socket 统一操作接口 ↓ sk 指针 【struct sock】 // 网络套接字通用基类 ↓ 内嵌扩展 【struct inet_sock】// IPv4 协议通用扩展层 ↓ 协议专属派生 【struct tcp_sock】 // TCP 传输层专属核心结构分层结构体关系图┌─────────────────────────────────────────────────────────┐ │ 用户态 API │ │ socket() bind() listen() accept() connect() send/recv │ └───────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ struct socket (上层文件对象) │ │ state / type / flags / file * / wq / sk * / ops * │ │ 作用对接VFS管理fd、阻塞、高层连接状态 │ │ 核心成员 │ │ struct sock *sk; // 指向底层真实套接字 │ │ struct proto_ops *ops; // 套接字操作函数集 │ └───────────────┬───────────────────────┬───────────────────┘ │ │ ▼ ▼ ┌───────────────────────┐ ┌─────────────────────────────┐ │ struct proto_ops │ │ │ │ 套接字方法函数表 │ │ │ │ bind() listen() │ │ │ │ accept() connect() │ │ │ │ sendmsg() recvmsg() │ │ │ │ poll() shutdown() │ │ │ │ setsockopt/getsockopt│ │ │ │ 不同协议实现不同ops │ │ │ │ TCP:inet_stream_ops │ │ │ │ UDP:inet_dgram_ops │ │ │ └───────────────────────┘ │ │ ▼ ┌─────────────────────────────────────┐ │ struct sock 通用基类 │ │ 所有网络套接字统一基础结构 │ │ sk_state(内核TCP状态) │ │ sk_family/sk_type 协议信息 │ │ 本机IP/远端IP、本机端口/远端端口 │ │ sk_receive_queue 接收skb队列 │ │ sk_write_queue 发送skb队列 │ │ sk_prot * 传输层协议函数表 │ │ sk_socket * 反向指向上层socket │ │ 超时、缓冲区、锁、引用计数 │ └───────────────────┬─────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ struct inet_sock IPv4扩展层 │ │ 继承sock补充IP层专属字段 │ │ TTL、服务类型、IP选项、分片控制 │ │ 组播、广播、路由相关配置 │ │ 内核通用IPv4套接字公共属性 │ └───────────────────┬─────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ struct tcp_sock TCP专属内核结构 │ │ 完全继承 sock inet_sockTCP独有核心数据 │ │ 1. 序列号snd_nxt / rcv_nxt / iss / irs │ │ 2. 滑动窗口拥塞窗口cwnd、接收窗口rwnd │ │ 3. 重传机制重传队列、超时重传、SACK、快速重传 │ │ 4. 拥塞控制BBR/CUBIC/reno 算法参数 │ │ 5. 三次握手、四次挥手状态机精细控制 │ │ 6. 延时ACK、保活探测、MSS、窗口缩放 │ │ 7. TCP定时器重传定时器、保活定时器、SYN定时器 │ └─────────────────────────────────────────────────────────┘函数调用完整执行流程用户态 connect() ↓ sys_connect() 系统调用入口 ↓ socket-ops-connect() // 调用 proto_ops.connect ↓ inet_stream_connect() // IPv4流式连接实现 ↓ sock-sk_prot-connect() // 调用 struct proto 传输层接口 ↓ tcp_v4_connect() // TCP IPv4 底层连接逻辑 ↓ 填充 tcp_sock 序列号、窗口、状态 ↓ 发送 SYN 报文进入 TCP_SYN_SENT 状态核心指针互指关系socket - sk上层指向底层通用socksocket - ops上层绑定协议操作函数集sock - sk_socket底层反向指回上层socketsock - sk_ops同上层proto_opssock - sk_prot指向tcp_prot / udp_prot传输层实现inet_sk(sk)sock强转inet_socktcp_sk(sk)sock强转tcp_sock核心总结socket管文件描述符、用户态视图、阻塞等待proto_ops统一封装系统调用屏蔽协议差异sock统一网络基础资源、数据包队列、四元组tcp_sock纯 TCP 协议专属逻辑流量控制、状态机、重传用户态接口封装将网络操作转为文件操作read/write/close。协议无关抽象通过ops屏蔽 TCP/UDP 差异统一接口。状态与资源管理跟踪连接状态、管理等待队列与文件生命周期。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价