C程序TCP Socket连接失败:端点未连接等错误排查求助
嘿,我来帮你拆解这两个报错的问题,结合你做1字节数据回传的性能测试场景,大概率是代码里的几个常见逻辑疏漏:
先搞懂两个报错的含义
“TCP server recv() failed: Transport endpoint is not connected”:这个错误说明你在一个没有和客户端建立有效连接的socket上调用了recv()/send(),简单说就是用错了socket描述符。
“TCP Sever send failed: Connection reset by peer”:这个是说客户端已经断开了连接(正常关闭或者异常崩溃),但服务器还在尝试往这个失效的连接里写数据。
常见错误场景及修复方法
误用监听Socket进行数据读写
服务器的正确流程是:创建监听socket → bind → listen → accept(拿到和客户端建立好的连接socket)→ 用这个连接socket做recv/send。如果你的代码跳过了accept(),直接用监听socket去读写,就会触发第一个报错。
修复示例:// 先创建并初始化监听socket int listen_fd = socket(AF_INET, SOCK_STREAM, 0); bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)); listen(listen_fd, 5); // 必须通过accept获取已连接的socket int conn_fd = accept(listen_fd, NULL, NULL); if (conn_fd == -1) { perror("accept failed"); return NULL; } // 之后只对conn_fd进行recv/send操作 char buf[1]; ssize_t recv_len = recv(conn_fd, buf, 1, 0);未检查recv返回值就盲目send
当客户端发送完1字节后,可能直接关闭了连接,此时recv()会返回0(表示客户端正常断开),如果这时候你还调用send(),就会触发第二个报错。
修复:每次recv后务必检查返回值:char buf[1]; ssize_t recv_len = recv(conn_fd, buf, 1, 0); if (recv_len == 0) { // 客户端已关闭连接,直接关闭socket退出 close(conn_fd); return NULL; } else if (recv_len == -1) { perror("TCP server recv() failed"); close(conn_fd); return NULL; } // 确认有有效数据再回传 ssize_t send_len = send(conn_fd, buf, 1, 0); if (send_len == -1) { perror("TCP Sever send failed"); close(conn_fd); return NULL; }多线程环境下的Socket管理混乱
如果你的服务器是多线程模式,可能出现多个线程操作同一个连接socket,或者某个线程提前关闭了socket,导致其他线程操作已失效的描述符。
修复:给每个新连接分配独立的线程处理,确保一个socket只被一个线程操作;线程处理完连接后,一定要关闭socket,避免后续误操作。
针对性能基准测试的额外优化
因为你是做性能测试,还有两个小建议能让结果更准确:
- 关闭Nagle算法:由于你传输的是1字节小数据,Nagle的延迟合并会影响测试结果,通过
setsockopt关闭:int opt = 1; setsockopt(conn_fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); - 考虑用IO多路复用(比如epoll、select)代替多线程,减少线程切换开销,更适合高并发的性能测试场景。
内容的提问来源于stack exchange,提问作者Joel no not that Joel

