You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

问题定位与修正

你的代码核心问题是赋值操作与比较操作的优先级错误,以及错误处理的函数误用:

  1. 优先级错误导致变量赋值异常
    =的优先级低于==,原代码中if((status = getaddrinfo(...) != 0))实际执行逻辑是status = (getaddrinfo(...) != 0),这会导致status被赋值为0或1,而非getaddrinfo的真实返回值。同理,socket和bind的赋值也存在同样问题,导致sockfd拿到的不是正确的套接字描述符,最终bind必然失败。

  2. 错误处理函数误用
    gai_strerror仅用于解析getaddrinfo的错误码,socket和bind失败时应该用strerror(errno)获取错误信息,因为这两个函数的错误码存在errno中。

  3. 遗漏资源释放与错误退出逻辑
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:35:22