问题描述
我正在尝试创建一个设置 Unix 套接字并侦听发送/接收数据的客户端的服务器。我做了一个 small repository 来重现这个问题。
服务器运行并且它可以从连接的客户端接收数据,但是我无法在服务器上没有错误的情况下从客户端读取服务器响应。
我已注释掉 client 和 server 上的违规代码。取消注释以重现问题。
线程 '' 在 Result::unwrap()
值上的 'call Err
处恐慌:Os { 代码:11,种类:WillBlock,消息:“资源暂时不可用”}',src/main.rs: 77:42
解决方法
您的代码调用 set_read_timeout
来设置套接字超时。它的文档指出,在 Unix 上,它会在超时的情况下导致 WouldBlock
错误,而这正是您遇到的情况。
至于您的客户端为什么超时,可能的原因是服务器调用了 stream.read_to_string(&mut response)
,它读取流直到文件结束。另一方面,您的客户端调用 write_all()
后跟 flush()
,并且(在取消注释违规代码后)尝试读取响应。但是尝试读取响应意味着流没有关闭,因此服务器将等待 EOF,您将陷入僵局。请注意,这些都不是 Rust 特有的;你会在 C++ 或 Python 中遇到完全相同的问题。
要解决此问题,您需要在通信中使用协议。一个非常简单的协议可能包括首先发送消息大小(以固定格式,长度可能为 4 个字节),然后才是实际的消息。从流中读取的代码将执行相同的操作:首先读取消息大小,然后读取消息本身。比发明自己的协议更好的是使用现有的协议,例如使用 serde
交换消息。