卷2 第16章 插口I/O
16.1 引言
本章讨论读写网络数据的系统调用。
16.2 代码介绍
sys/socket.h:API定义sys/socketvar.h:socket结构sys/uio.h:uio结构kern/uipc_syscalls.c:系统调用kern/uipc_socket.c:插口层
16.3 插口缓存
sockbuf结构
| 成员 | 说明 |
|---|---|
| sb_mb | mbuf链 |
| sb_cc | 字节数 |
| sb_hiwat | 高水位标记 |
| sb_lowat | 低水位标记 |
| sb_mbmax | 最大mbuf数 |
| sb_flags | 标志 |
默认缓存大小
| 协议 | 发送 | 接收 |
|---|---|---|
| TCP | 8192 | 8192 |
| UDP | 9216 | 41600 |
16.4 写系统调用
四种写调用
| 调用 | 说明 |
|---|---|
| write | 简单写 |
| writev | 分散-收集写 |
| sendto | 指定目的地址 |
| sendmsg | 最通用 |
iovec结构
struct iovec {
caddr_t iov_base;
int iov_len;
};标志 标志 说明 MSG_DONTROUTE 旁路路由 MSG_DONTWAIT 不等待 MSG_EOR 记录结束 MSG_OOB 带外数据
16.5 sendmsg系统调用
支持控制信息
支持分散-收集
16.6 sendit函数
初始化uio结构
复制地址和控制信息
调用sosend
uiomove函数 在进程和内核间传输数据
处理iov数组
16.7 sosend函数
可靠协议 缓存数据直到确认
PR_ATOMIC:整个报文
不可靠协议 立即发送
不缓存
处理流程 加锁发送缓存
检查空间
复制数据到mbuf
传递数据到协议
PRU_SEND或PRU_SENDOOB
16.8 读系统调用
四种读调用 调用 说明 read 简单读 readv 分散读 recvfrom 接收地址 recvmsg 最通用
16.9 recvmsg系统调用
接收控制信息
返回源地址
16.10 recvit函数
初始化uio结构
调用soreceive
返回地址和控制信息
16.11 soreceive函数
带外数据处理 MSG_OOB标志
SO_OOBINLINE选项
标志 标志 说明 MSG_PEEK 查看不取走 MSG_WAITALL 等待全部数据 MSG_DONTWAIT 不等待 处理流程 加锁接收缓存
等待数据
处理地址和控制信息
传输数据
处理MSG_WAITALL
16.12 select系统调用
监控事件 事件 说明 读 数据可读 写 可写 异常 带外数据 selscan函数 遍历描述符集
调用soo_select
soo_select函数 检查插口状态
记录等待进程
selwakeup函数 唤醒等待进程
处理冲突
16.13 小结
sosend和soreceive是I/O的核心函数。select支持多路I/O监视。