C语言Socket编程问题:套接字创建与绑定返回错误
C语言Socket编程:bind绑定失败问题排查
问题描述
我正在编写一个基于Socket的C语言简易HTTP服务器,作为新手遇到了bind绑定失败的问题。运行程序时报错,自行检查代码未找到问题,附上错误截图及代码,请求帮忙定位问题。
运行错误截图:
原代码
#include <stdio.h> #include <sys/socket.h> #include <errno.h> #include <string.h> #include <netdb.h> #define PORT "4390" int main(){ int status; struct addrinfo hints, *res; int sockfd; memset(&hints,0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; if((status = getaddrinfo("localhost",PORT,&hints,&res) != 0)){ fprintf(stderr,"getaddrinfo error: %s\n",gai_strerror(status)); } if((sockfd = socket(res->ai_family,res->ai_socktype,0) == -1)){ fprintf(stderr,"socket error %s\n",gai_strerror(sockfd)); } int bindstatus; if((bindstatus = bind(sockfd,res->ai_addr,res->ai_addrlen) == -1)){ fprintf(stderr,"bind error %s\n", gai_strerror(bindstatus)); } printf("%d\n",bindstatus); return 0; }
问题定位与修正
你的代码核心问题是赋值操作与比较操作的优先级错误,以及错误处理的函数误用:
优先级错误导致变量赋值异常
=的优先级低于==,原代码中if((status = getaddrinfo(...) != 0))实际执行逻辑是status = (getaddrinfo(...) != 0),这会导致status被赋值为0或1,而非getaddrinfo的真实返回值。同理,socket和bind的赋值也存在同样问题,导致sockfd拿到的不是正确的套接字描述符,最终bind必然失败。错误处理函数误用
gai_strerror仅用于解析getaddrinfo的错误码,socket和bind失败时应该用strerror(errno)获取错误信息,因为这两个函数的错误码存在errno中。遗漏资源释放与错误退出逻辑
getaddrinfo成功后需要调用freeaddrinfo(res)释放内存;如果getaddrinfo失败,后续使用res会导致空指针访问,应该直接退出程序。
修正后的代码
#include <stdio.h> #include <sys/socket.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <stdlib.h> #define PORT "4390" int main(){ int status; struct addrinfo hints, *res; int sockfd; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; // 修正括号位置,正确获取getaddrinfo返回值并判断 if( (status = getaddrinfo("localhost", PORT, &hints, &res)) != 0 ){ fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status)); return EXIT_FAILURE; } // 修正括号位置,使用res->ai_protocol更规范,错误处理用strerror(errno) if( (sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1 ){ fprintf(stderr, "socket error: %s\n", strerror(errno)); freeaddrinfo(res); return EXIT_FAILURE; } int bindstatus; // 修正括号位置,错误处理用strerror(errno) if( (bindstatus = bind(sockfd, res->ai_addr, res->ai_addrlen)) == -1 ){ fprintf(stderr, "bind error: %s\n", strerror(errno)); close(sockfd); freeaddrinfo(res); return EXIT_FAILURE; } printf("bind success, status: %d\n", bindstatus); // 释放资源 close(sockfd); freeaddrinfo(res); return EXIT_SUCCESS; }
内容的提问来源于stack exchange,提问作者devMe
相关产品推荐
相关产品推荐

