sockets - Unix套接字的双向通信
问题描述
我正在尝试创建一个设置 Unix 套接字并侦听发送/接收数据的客户端的服务器。我制作了一个小型存储库来重新创建问题。
服务器运行并且它可以从连接的客户端接收数据,但是我无法从客户端读取服务器响应而不会在服务器上出现错误。
我已经注释掉了客户端和服务器上的违规代码。取消注释两者以重现问题。
当响应客户端的代码未注释时,我在服务器上收到此错误:
线程''在'调用
Result::unwrap()
一个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
.
推荐阅读
- javascript - 如何在 $(window).resize 函数之外获取 window.width() 值?
- c - 使用字符串文字初始化数组时的不同程序集
- javascript - 如何使 Event DOM Listener 适应 Google Maps JavaScript API v3.35
- angular - 如何使用 Angular 在 Web 浏览器中使用 USB 智能卡进行身份验证
- javascript - 带有crypto-js的PHP hash_hmac()二进制输出
- ios - iOS粘贴板奇怪的随机崩溃
- mysql - 在数据库中存储文件结构
- ios - UICollectionView 单元格居中,为什么?
- python - 如何在 xpath 命令中使用 python scrapy 进行 Web 抓取的任意值
- visual-studio-code - Visual Studio 代码:更改尖括号 html 格式