C++ Socket循环收发整数失败 recv返回-1且errno为0排查
故障诱因说明
直接根因
客户端循环接收账号数值的代码存在指针传参错误,漏写了取地址符,给recv传入了非法空指针:
错误代码片段:
int32_t account = 0; recv(socket, reinterpret_cast<char*>(account), sizeof(account), 0); // 错误行
对比接收账号总数的正确写法,接收账号时没有对account变量取地址,直接把int类型的变量初始值0强转成了char*指针,相当于传入了指向内存地址0x0的空指针作为接收缓冲区。
现象对应解释
- 账号总数能正常接收:接收
n_accounts的recv调用正确传入了变量地址&n_accounts,指向合法内存空间,可以正常写入数据。 - 循环内
recv返回-1:recv尝试向空指针指向的非法内存地址写入数据,触发内存访问违规,调用直接失败。 - errno值为0:这类用户态传入非法指针的错误,在部分操作系统的socket实现中,会在进入内核逻辑前就完成参数校验直接返回,不会设置errno值,因此会出现返回失败但errno为0的情况。
修复方式
将错误行修改为传入account变量的地址即可:
recv(socket, reinterpret_cast<char*>(&account), sizeof(account), 0);
额外提示:当前代码未处理
send/recv的返回值,TCP为字节流协议,单次调用不保证能发送/接收完指定长度的所有数据,生产环境需要加循环处理短读/短写情况,否则后续仍可能出现数据错乱问题。
内容的提问来源于stack exchange,提问作者Abstruxt
相关产品推荐
相关产品推荐

