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

C Socket编程自定义read_all函数阻塞、put命令失效问题排查

问题排查结论
  • 首先read_all函数本身的读写逻辑是正确的,你观察到的阻塞现象是因为read系统调用没有收到客户端发送的对应数据,内核默认会阻塞等待直到有数据到达/对端断开连接,问题出在发送端的参数错误和返回值判断逻辑错误。
  • 第一个核心错误:发送长度的write_all调用参数与返回值判断完全不匹配
    你当前发送长度的代码存在逻辑漏洞:
    write_all(descr, &sen , sizeof(len))) != len)
    
    你要发送的是存储长度的sen变量,第三个参数应该传sizeof(sen)(也就是4字节,对应网络字节序的32位整数),但你判断返回值是否等于len(protobuf打包后的消息体长度,比如你当前场景的6)。这会导致只要len不等于4,就会判定发送失败,客户端提前终止逻辑、关闭连接,服务端自然收不到后续的6字节数据,卡在read调用。
    正确的判断逻辑应该是:
    if (write_all(descr, &sen, sizeof(sen)) != sizeof(sen)) {
        // 发送长度失败,处理错误
    }
    
  • 第二个错误:疑似函数名笔误
    你写的unsigned sen = htoml(len)大概率是htonl(主机字节序转网络字节序32位)的笔误,如果实际代码里确实写的是htoml,会导致序列化的长度值错误,服务端用ntohl转换后得到错误的长度值,后续读取逻辑异常。
  • 第三个隐患:类型不匹配的隐式转换
    read_all的第三个参数是有符号int类型,你传入的len是无符号类型,如果后续消息体长度超过int的最大值,会溢出为负数传入read_all,导致left初始值为负,直接跳过循环返回0,引发逻辑错误。建议将read_all、write_all的长度参数统一改为size_t(无符号整数类型,专门表示长度)。
  • 补充注意:你提到「读取长度的逻辑能正常返回0符合预期」是错误的,read_all返回0说明对端已经关闭了连接,正常读取长度的场景下应该返回sizeof(rec)(也就是4字节)才符合预期,这也验证了客户端提前关闭连接的结论。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:36:03