c++ - 如何用winsock正确recv?
问题描述
我正在编写一个简单的 http 服务器进行测试,但我很困惑应该如何判断请求的结束位置。
recv() 在错误时返回负数,在连接关闭时返回 0,在接收数据时返回正数,当没有更多数据时它只是阻塞。
我可以创建一些科学怪人,在一个线程上连续接收并检查它是否在另一个线程上阻塞,但必须有更好的方法来做到这一点......我如何判断暂时是否没有更多字节要读取没有阻塞?
解决方案
首先,在读取 HTTP 请求时应该遵循 HTTP 协议:
- 继续从套接字读取,直到
\r\n\r\n
收到 - 解析标题
- 如果
Content-Length
指定,则额外读取请求有效负载的那么多字节 - 处理 HTTP 请求
- 发送 HTTP 响应
- 关闭套接字 (HTTP/1.0) 或 (HTTP/1.1) 句柄 keep-alive、内容编码、传输编码、预告片等,可能从步骤 1 开始重复。
为了处理可能行为不端的客户端,在使用阻塞套接字时,习惯上在发出recv
或send
调用之前设置套接字超时。
DWORD recvTimeoutMs = 20000;
setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&recvTimeoutMs, sizeof(recvTimeoutMs));
DWORD sendTimeoutMs = 30000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&sendTimeoutMs, sizeof(sendTimeoutMs));
当 arecv
或send
超时时,它将失败并WSAGetLastError
给出WSAETIMEDOUT
(10060)。
推荐阅读
- python - 现有模型中未找到模型错误
- javascript - 唯一的 DataTable 列标题工具提示
- php - JSON 日期转 PHP 日期
- c# - 机器人框架 DialogContext.Continue 不起作用
- angularjs - Angularjs 控制器已定义但从未使用过
- c++ - 是否有任何 2 补码平台/编译器,其中带符号的移位不做通常的事情?
- python - Selenium 被检测到,并且在第一次打开Bloomberg URL 后立即弹出验证码
- java - 项目中所需库 tomcat-embed-websocket 的存档无法读取或不是有效的 ZIP 文件
- javascript - 反应动态表创建
- javascript - 未捕获的 ReferenceError:未定义数据点。从 api 调用 json 数据时