首页 > 解决方案 > Unix套接字的双向通信

问题描述

我正在尝试创建一个设置 Unix 套接字并侦听发送/接收数据的客户端的服务器。我制作了一个小型存储库来重新创建问题。

服务器运行并且它可以从连接的客户端接收数据,但是我无法从客户端读取服务器响应而不会在服务器上出现错误。

我已经注释掉了客户端服务器上的违规代码。取消注释两者以重现问题。

当响应客户端的代码未注释时,我在服务器上收到此错误:

线程''在'调用Result::unwrap()一个Err值时惊慌失措:Os {代码:11,种类:WillBlock,消息:“资源暂时不可用”}',src/main.rs:77:42

MRE链接

标签: socketsrustunix-socket

解决方案


您的代码调用set_read_timeout以在套接字上设置超时。它的文档指出,在 Unix 上,它会在WouldBlock超时的情况下导致错误,这正是发生在你身上的事情。

至于为什么您的客户端超时,可能的原因是服务器调用stream.read_to_string(&mut response),它读取流直到文件结束。另一方面,您的客户端调用write_all()后跟flush(), 和(在取消注释有问题的代码之后)尝试读取响应。但是尝试读取响应意味着流没有关闭,因此服务器将等待 EOF,并且您手头有死锁。请注意,这些都不是 Rust 特有的。你会在 C++ 或 Python 中遇到完全相同的问题。

要解决此问题,您需要在通信中使用协议。一个非常简单的协议可以包括首先发送消息大小(以固定格式,长度可能为 4 个字节),然后才发送实际消息。从流中读取的代码也会这样做:首先读取消息大小,然后读取消息本身。比发明自己的协议更好的是使用现有的协议,例如使用serde.


推荐阅读