问题描述
我正在为测试编写一个简单的 http 服务器,但我对如何判断请求的结束位置感到很困惑。
recv() 出错时返回负数,连接关闭时返回 0,接收数据时返回正数,当没有更多数据时,它只是阻塞。
我可以创建一些科学怪人,它在一个线程上不断接收数据并检查它是否在另一个线程上阻塞,但必须有更好的方法来做到这一点......我如何判断是否没有更多字节可供读取暂时没有阻塞?
解决方法
首先,读取HTTP请求时要遵循HTTP协议:
- 继续从套接字读取直到收到
\r\n\r\n
- 解析标题
- 如果指定了
Content-Length
,则额外读取请求负载的那么多字节 - 处理 HTTP 请求
- 发送 HTTP 响应
- 关闭套接字 (HTTP/1.0) 或 (HTTP/1.1) 句柄保持活动、内容编码、传输编码、预告片等,可能从步骤 1 开始重复。
为了处理潜在的行为不端的客户端,在使用阻塞套接字时,通常会在发出 recv
或 send
调用之前设置套接字超时。
DWORD recvTimeoutMs = 20000;
setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(const char *)&recvTimeoutMs,sizeof(recvTimeoutMs));
DWORD sendTimeoutMs = 30000;
setsockopt(socket,SO_RCVTIMEO,(const char *)&sendTimeoutMs,sizeof(sendTimeoutMs));
当 recv
或 send
超时时,它将失败,WSAGetLastError
给出 WSAETIMEDOUT
(10060)。