核心功能示例
这一组示例一个目录演示一个 rdmanet 核心特性,
基本对应第二部分讲的那些 API。想学某个功能,直接读对应目录的 main.go 即可。
速查表
| 目录 | 演示的特性 | 对应章节 |
|---|---|---|
echo-msg | RC 消息语义(SendMsg/RecvMsg),最小起点 | 高层 rdmanet |
echo-stream | 字节流适配器(Read/Write,io.ReadWriteCloser) | 高层 rdmanet |
handshake-dial | TCP 带外握手建连(WithHandshake) | 连接方式 |
packet | UD 数据报(PacketConn,WriteTo/ReadFrom) | RC/UD |
batch | 批量 I/O 摊薄开销(SendBatch/RecvBatch) | 性能选项 |
zerocopy | 零拷贝发送(AllocBuffer/SendBuffer) | 性能选项 |
registry | UD 地址带外发现(NewRegistry/LookupAddr) | 性能选项 |
pollmode | CQ 轮询模式选择(WithPollMode) | 性能选项 |
逐个说明
echo-msg —— 最小起点
RC 消息语义的最小回显:服务端 Accept 后 RecvMsg,客户端 SendMsg。
想跑通第一个 RDMA 程序,从它开始。
go run ./examples/echo-msg -l 0.0.0.0:18515 # 服务端
go run ./examples/echo-msg 33.0.226.25:18515 # 客户端
echo-stream —— 字节流
把 Conn 当 io.ReadWriteCloser 用,演示字节流适配器跨消息边界读字节的行为。
与 echo-msg 对照,能直观体会「消息语义 vs 字节流」的差别。
handshake-dial —— TCP 握手建连
用 WithHandshake() 走 TCP 带外握手而非默认 rdma_cm。除了多一个 Option,
收发代码与 echo-msg 一模一样——印证两种连接方式产出同样的 Conn。
packet —— UD 数据报
PacketConn 的 WriteTo/ReadFrom,类比 net.UDPConn。
UD 无连接,客户端用服务端打印的 Addr 字符串(gid%qpn)来寻址。
# 服务端启动时打印自己的 Addr,例如 fe80:...:0001%0x1a2b
go run ./examples/packet
# 客户端把那串 Addr 传进来
go run ./examples/packet 'fe80:0000:...:0001%0x1a2b'
batch —— 批量 I/O
一次 SendBatch 发多条、一次 RecvBatch 收多条,摊薄每次调用的固定开销。
例子里客户端发 8 条,服务端一次性收齐。
zerocopy —— 零拷贝发送
填 buf.Bytes() 后调 SendBuffer,直接从预注册内存 DMA 发出,省掉到 bounce buffer 的拷贝。
缓冲区按其完整分配长度发送(例子是 64 字节,余下补零)。
registry —— UD 地址发现
UD 端点把自己的 Addr 以名字登记到注册表,对端按名字查,免去手动拷贝 Addr。
注册表服务本身是纯 Go,无需 RDMA,可单独起。
pollmode —— 轮询模式
用 --poll=busy|event 切换 CQ 排空策略,直观对比延迟与 CPU 占用(见
性能选项的权衡)。