【发布时间】:2019-09-03 19:02:22
【问题描述】:
我想接收分块发送的请求。为了做到这一点,我使用了一个带有 recv 的 TCP 套接字。我循环recv如下:
while ((total_recv < MAX_HEADER) && (received = recv(client, req_buffer, CHUNK, 0)) > 0) {
total_recv += received;
if (strstr(req_buffer, delimiter) != NULL)
break;
}
我的目标是在收到以分隔符结尾的标头时停止接收。我不能保证分隔符存在,因此如果 total_recv 大于或等于最大已知标头大小,我会中断循环。
我不喜欢这样。困扰我的是我可以收到一个没有小于最大标头大小的分隔符的数据包。在这种情况下,我必须假设 recv 将继续增加 total_recv 直到循环中断。我通过读取套接字 API 知道 recv 将返回读入缓冲区的字节数,错误时返回 -1,如果连接已关闭,则返回 0。
有没有更好的方法来循环 recv 而不依赖于超时?当连接打开但发送方或接收方没有传输数据时,send() 和 recv() 究竟返回了什么?
【问题讨论】:
-
"我的目标是在我收到以分隔符结尾的标头时停止接收" - 那么您可能需要读取 1 个字符直到到达分隔符的时间。如果标头的大小不是
CHUNK的偶数倍,那么您的recv循环将在到达标头末尾时读取太多数据。此外,您对strstr()的使用已被破坏,因为req_buffer不是以空值终止的,并且您没有在每次循环迭代时将收到的每个req_buffer连接到累积缓冲区中。 -
"我不能保证分隔符存在" - 为什么不呢?您正在使用哪种协议,它不能保证存在分隔符?如果基于 TCP 的协议不提供任何可靠地检测标头结尾的方法,这将是非常不寻常且非常不稳定的。您确定实际标头大小未在标头本身内编码吗?当不使用终止分隔符时,这会更有意义。