Linux下C++编写TCP服务端时accept返回-1的问题求助
Socket Accept 返回-1的排查建议
1. 修复accept的第三个参数(直接导致失败的核心原因)
你的accept调用中第三个参数传了NULL,这是不符合规范的错误用法。accept需要传入一个指向socklen_t变量的指针,用来存储客户端地址结构体的实际大小。修正代码如下:
sockaddr_in their_add; socklen_t addr_len = sizeof(their_add); int connection = accept(this->m_Socket, (sockaddr*)&their_add, &addr_len);
传NULL属于未定义行为,会直接触发accept调用失败。
2. 检查前置调用的错误(socket/bind/listen)
你的构造函数中完全没有检查socket、bind、listen的返回值,这些步骤如果失败,会导致后续accept使用无效的套接字描述符。给每个函数添加错误检查逻辑:
Server::Server(int port) { m_Port = port; int server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket == -1) { perror("socket creation failed"); exit(EXIT_FAILURE); } sockaddr_in server_address; server_address.sin_family = AF_INET; server_address.sin_port = htons(port); server_address.sin_addr.s_addr = INADDR_ANY; if (bind(server_socket, (sockaddr *)&server_address, sizeof(server_address)) == -1) { perror("bind failed"); close(server_socket); exit(EXIT_FAILURE); } if (listen(server_socket, SOMAXCONN) == -1) { perror("listen failed"); close(server_socket); exit(EXIT_FAILURE); } m_Socket = server_socket; }
常见的前置错误场景:
socket失败:系统资源不足或协议不支持bind失败:端口被占用(错误码EADDRINUSE)、无权限绑定1024以下端口(需root权限)listen失败:套接字不是有效描述符
3. 获取具体错误码定位问题
当accept返回-1时,立即打印错误信息,这是最直接的排查手段:
int connection = accept(...); if (connection == -1) { perror("accept failed"); // 或者用strerror输出更详细的错误描述 std::cerr << "accept error detail: " << strerror(errno) << std::endl; continue; // 继续等待下一个连接请求 }
常见的accept错误码:
EBADF:传入的socket不是有效的文件描述符EINVAL:套接字未处于监听状态(listen未调用或调用失败)EMFILE:进程打开的文件描述符数量达到系统上限
4. 其他辅助排查点
- 若绑定的是1024以下端口,必须用root权限运行程序,否则
bind会直接失败 - 检查目标端口是否被其他程序占用,可执行命令:
netstat -tulpn | grep <你的端口号> - 你的代码中
read后直接使用buffer构造std::string,但read不会自动添加字符串终止符,可能导致垃圾数据,建议根据read返回值处理:ssize_t bytes_read = read(connection, buffer, sizeof(buffer)-1); if (bytes_read > 0) { buffer[bytes_read] = '\0'; // 手动添加终止符 std::string message(buffer); // 后续处理逻辑 } - 当前代码创建线程后立即
join,相当于串行处理连接,未实现真正并发,若需要并发,可改用detach或把线程存入容器管理
内容的提问来源于stack exchange,提问作者AdriaNn01
相关产品推荐
相关产品推荐

