std::net 的 TCP API 很小,但每个细节都值得验证:端口怎么分配、各种错误长什么样、为什么「一次 write 一次 read」不成立、半关闭是什么、NODELAY 影响多大。这篇用本机的回环地址把它们都跑一遍。
编译:成功
运行(退出码 0):
监听地址 127.0.0.1:<端口>(端口由系统分配:true)
服务端:来自 <客户端地址> 的 5 字节已回显(对端 IP 127.0.0.1,是回环地址: true)
客户端:发 "hello",收到 "hello"
服务端:来自 <客户端地址> 的 6 字节已回显(对端 IP 127.0.0.1,是回环地址: true)
客户端:发 "世界",收到 "世界"非阻塞与多路复用见非阻塞 IO;异步版本见Tokio TCP Echo Server。
编译:成功
运行(退出码 0):
连接一个没人监听的端口:kind = ConnectionRefused,os_error = Some(61)
同一个地址 bind 第二次:kind = AddrInUse,os_error = Some(48)
读超时 100 ms:kind = WouldBlock(实际等了约 100 ms) 编译:成功
运行(退出码 0):
发送端分 3 次 write 各 4 字节,接收端一次 read 读到 12 字节:"AAAABBBBCCCC"(消息边界没有保留)
再 read:0 字节(0 = 对端已关闭,读到 EOF)HTTP 如何在字节流上分帧见HTTP 请求的底层实现。
编译:成功
运行(退出码 0):
客户端 shutdown(Write) 之后,服务端 read_to_end 返回,回复 "收到 12 字节"
服务端结果 (12, None)
客户端不关闭写端:服务端 read_to_end 在 400 ms 超时后失败,返回 (12, Some(WouldBlock))(已经读到的 12 字节仍留在 Vec 里) 编译:成功
运行(退出码 0):
请求分两次 write(2 字节 + 2 字节)再等回复,每轮往返:默认 44 µs,set_nodelay(true) 18 µs只在本机回环地址上测量,绝对数值和真实网络无关。