Linux下recv循环接收出现无限非阻塞循环问题求助
问题分析与解决
先看你提供的代码:
std::array<char, 256> buffer; while (1) { // top loop while (1) { // inner loop n = recv(sockfd, &buffer[0], buffer.size() - 1, 0); if (n == 0) { break; } memset(buffer.data(), 0, 256); } n = send(sockfd, "33", 3, MSG_NOSIGNAL); }
核心原因
recv返回0的唯一标准含义是:TCP连接的对端已经正常关闭了连接(发送了FIN包)。一旦进入这个状态,该socket的读通道就会处于EOF状态,后续所有recv调用都会直接返回0,不会再阻塞等待数据。
你的现象完整逻辑是:
- 首次
recv阻塞:此时连接状态正常,对端没发数据也没关连接,所以recv阻塞等待。 - 执行一次
send后,对端收到数据,触发了它的关闭逻辑(比如对端收到数据就主动断连)。 - 你的程序再次进入内层循环调用
recv,此时读通道已EOF,recv直接返回0,触发break跳出内层循环。 - 外层循环继续执行
send(此时连接已关闭,send实际会返回-1,但MSG_NOSIGNAL避免了进程被终止),之后又回到内层循环,recv还是返回0,如此往复形成无限循环。
额外代码问题
- 当
recv成功读到数据(n>0)时,立刻用memset清空buffer,会直接丢失刚接收的数据,这完全不符合正常的收数据逻辑。 send的长度参数填错了:"33"是两个字符,你传3会把字符串末尾的\0也发出去,TCP传输不需要这个终止符,应该填2。
内容的提问来源于stack exchange,提问作者3088 K
相关产品推荐
相关产品推荐

