在不知道消息长度之前处理阻塞的 recv() 函数并且不想使用 asy I/O

handle blocked recv() function without knowing the message length before and don't want to use asy I/O

我正在创建一个非常简单的服务器,它接受来自浏览器 (Safari) 的 http 请求并响应一些转储 HTTP 响应,例如 "Hello World" 消息。

我的程序在 recv() 函数上被阻塞,因为它不知道客户端(浏览器)是否完成发送 HTTP 请求,而 recv() 是一个阻塞函数。 (一个很典型的问题)

我找到的最流行的答案是在发送消息之前先发送消息的长度。 这个解决方案很好,但对我不起作用,因为我无法控制从客户端发送的内容。据我所知,浏览器在发送真实消息之前不会发送任何消息长度。

第二个最受欢迎的答案是使用 asy I/O,例如 select() 或 poll()。但是,就我个人而言,我认为这并不是一个好的策略,因为一旦我已经收到来自客户端的所有请求消息,那么,当然,我想进入下一步来处理请求。为什么我还要浪费我的时间和资源去等待那些永远不会到来的东西,即使它不再阻塞了? (创建线程提出了类似的问题)

我想到的解决方案是检查接收到的消息大小是否等于缓冲区大小。例如,假设我将recvBufferSize设置为32,请求消息的总大小为70。那么我将收到三个大小分别为32、32、6的数据包。 我可以看出客户端已完成发送请求,因为最后一个数据包的大小不等于 接收缓冲区大小(32)。

但是,如您所见,请求消息的大小为64/96/128时出现问题......

其他方法可能像设置超时,但我不确定它们是否好。

而且我想自己构建所有东西,所以我可能对任何库都不感兴趣,例如 zeromq 或 Boost.Asio

有没有大佬可以给我一些建议,或者提供一些其他更好的方法来解决问题?非常感谢!

如果您正在实施 HTTP 协议,则需要研究 HTTP RFC。有几种不同的方法可以知道请求长度,从 Content-length header 开始,如果客户端使用分块传输编码,则可以知道分块的组合长度。