c - 如何在 C 编程中从 BSD 套接字中的 recv() 接收 CHUNK 数据?
问题描述
我已经使用套接字在 C 中实现了一个 websocket 客户端库。它与许多 websocket 服务器一起正常工作。但是当我尝试连接我的一个客户服务器时,websocket 消息来自许多数据块。对于所有其他服务器,当我使用 recv() 时,它将完全接收一个完整的 websocket 帧,但是这个特定的服务器将在 2 个 TCP 数据包中发送一个 websocket 帧,所以我必须再次使用 recv() 来获取剩余的 websocket 帧。然后我尝试用一些 websocket 客户端工具检查这个服务器,它工作正常。我需要知道逻辑,为此实现 recv() 以及如何连接和计算 websocket 帧何时被完全接收以解析数据?请有人帮我解决这个问题。
while(1){
ws_recv_ret = recv(*ws_sock, ws_recv, 1024, 0);
ws_parser_execute(&ws_frame_parser1, ws_recv);
}
解决方案
TCP recv 允许接收任意数量的字节,最多为您要求的最大数量。“数据包”是完全不可预测的,您绝对不能依赖它们。
你如何判断 websocket 框架的大小?当然,您使用 websocket 协议。websocket 标头告诉您 websocket 帧中有多少字节。您需要继续调用 recv 直到获得所有字节。
如果您接收太多字节,那么您需要保存额外的字节并将它们用于下一帧。如果您仔细计算一次要接收多少字节,那么您将永远不会收到太多,但是许多程序确实尝试接收尽可能多的字节,因为这样更有效,因此它们需要处理额外的字节。
当然,因为“数据包”是完全不可预测的,所以“数据包”可能会在标题中间结束。所以你需要继续调用recv直到你有整个头,然后你知道有多少字节,然后你需要继续调用recv直到你有所有的字节。
更烦人的是,websocket 标头可以有不同的大小。所以你需要继续调用 recv 直到你知道 header 有多大,然后你需要继续调用 recv 直到你有整个 header,然后你需要继续调用 recv 直到你有所有的字节。
推荐阅读
- javascript - 是否可以在没有 jest.mock('module') 的情况下在 NodeJS 中使用 Jest 模拟 API 调用?
- python - 在 python 中过滤两列并在每列中选择适用的字段
- java - 线程“主”java.lang.ClassCastException 中的异常:类 [B 不能强制转换为类 [C([B 和 [C 在加载器“引导程序”的模块 java.base 中)
- python - ValueError:层顺序的输入 0 与层不兼容:输入形状的预期轴 -1 具有值 1
- vba - 将波斯文文本从文件插入 PowerPoint
- python - pyspark 填充 spark 数据框中每个 id 的缺失数据
- svg - 在 Seed Rust 应用程序中为 SVG 文本元素调用 getBBox
- python - 在 python 中提取项目进行演示 - 我有一个从 Outlook 中获取的列表,但需要将这些项目分解为单独的字符串
- qt - 无法让 Qt Creator 调试在 Windows 10 上运行
- python - 基本的While循环迭代顺序?