You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++服务器读取curl请求时read()函数阻塞无法结束问题求助

问题根因分析

1. curl请求时服务端read循环阻塞的原因

你当前的读取逻辑是持续调用read()直到返回值<=0才退出,而read()返回0的唯一触发条件是对端关闭了连接的写方向(发送FIN包)。
curl默认使用HTTP/1.1协议,开启Keep-Alive复用连接,发送完请求后会保持连接打开等待服务端返回响应,不会主动关闭写端,因此read()会一直阻塞等待新数据,不会退出循环。
你提到的真实第三方客户端能正常完成读取,是因为该客户端发送完请求后就主动关闭了写方向的连接,触发read()返回0。

2. 第三方客户端上报“Connection Refused”错误的原因

能正常收到客户端请求说明三次握手已经完成,客户端实际收到的大概率是连接重置错误(表述为Connection Refused属于常见误报):你当前的服务端逻辑读取完请求后没有返回任何HTTP响应,直接关闭连接时,如果socket内核缓冲区还有未处理的客户端数据,TCP会直接发送RST包断开连接,客户端就会收到连接异常的报错。

解决方案

方案1:临时调整curl命令适配现有服务端逻辑

在curl命令中添加Connection: close头,让curl发送完请求后主动关闭连接,即可触发read()返回0退出循环:

curl -X POST -H "content-type:application/json" -H "content-length:50" -H "Connection: close" "http://192.168.1.44:4444/" --data "{\"id\":111111,\"data\":{\"from\":\"USD\",\"to\":\"ETH,BTC\"}}"

也可以添加--http1.0参数使用默认关闭长连接的HTTP/1.0协议,效果一致。

方案2:修改服务端读取逻辑符合HTTP协议规范(推荐)

现有读取逻辑仅适用于短连接一次性发完就关的场景,不符合HTTP协议的设计。正确的读取逻辑应该:

  • 先读取HTTP请求头,解析出Content-Length字段的值
  • 按解析得到的长度读取指定大小的请求体,读到指定长度后直接退出循环,不需要等待对端关闭连接

方案3:修复第三方客户端报错问题

处理完请求后,先向客户端返回合法的HTTP响应,再正常关闭连接。最简单的响应示例如下:

const char* response = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n";
write(client_fd, response, strlen(response));
// 延迟关闭避免RST:先调用shutdown(client_fd, SHUT_WR),等待对端FIN后再close

内容的提问来源于stack exchange,提问作者Zephyrus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:15:07