首页 > 解决方案 > 如何在 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);
}

标签: csocketswebsockettcp

解决方案


TCP recv 允许接收任意数量的字节,最多为您要求的最大数量。“数据包”是完全不可预测的,您绝对不能依赖它们

你如何判断 websocket 框架的大小?当然,您使用 websocket 协议。websocket 标头告诉您 websocket 帧中有多少字节。您需要继续调用 recv 直到获得所有字节。

如果您接收太多字节,那么您需要保存额外的字节并将它们用于下一帧。如果您仔细计算一次要接收多少字节,那么您将永远不会收到太多,但是许多程序确实尝试接收尽可能多的字节,因为这样更有效,因此它们需要处理额外的字节。

当然,因为“数据包”是完全不可预测的,所以“数据包”可能会在标题中间结束。所以你需要继续调用recv直到你有整个头,然后你知道有多少字节,然后你需要继续调用recv直到你有所有的字节。

更烦人的是,websocket 标头可以有不同的大小。所以你需要继续调用 recv 直到你知道 header 有多大,然后你需要继续调用 recv 直到你有整个 header,然后你需要继续调用 recv 直到你有所有的字节。


推荐阅读