Search code examples
csocketsnetwork-programming

Trouble with socket programming: Socket creation and binding returning errors in C


I'm working on a C program that involves socket programming basically I'm trying to write a simple HTTP server I'm noob to this, and I'm encountering issues with binding. I've written the following code, but I'm getting errors during binding. I've checked the code and can't seem to find the issue. Can anyone help me identify what's wrong?

when i run the program i get this output

error for run

here is my code

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

Solution

  • The main problem is caused by an attempt to write compact code without properly understanding operator precedence. In addition to that there are some other errors.

    Take this part:

        if((sockfd = socket(res->ai_family,res->ai_socktype,0) == -1)){
            ...report error
        }
    

    What you attempt to do here is

        sockfd = socket(res->ai_family,res->ai_socktype,0);
        if (sockfd == -1) {
            ...report error
        }
    

    What you do instead is

        sockfd = ( socket(res->ai_family,res->ai_socktype,0) == -1 );
        if (sockfd) { ...
    

    Thus, sockfd will not be the sockfd but be likely 0, because 0 means false and false is the result of a == comparison between what socket returned (the file descriptor) and -1.

    Thus bind will be called later with a sockfd of 0, which isn't a valid socket. Thus bind will fail. In the code with bind you make the same kind of precedence error again.

    The best way to fix is to write compact code only if you really understand what you are doing, in this case understanding operator precedence and properly applying parentheses where needed. I recommend instead to write more verbose code in order to avoid such easy to miss problems.


    Apart from that gai_strerror does not expect the return value of socket or bind as input. It should not even be used to deal with the error of these functions, but is used for handling errors in getaddrinfo. See the documentation for details. What you likely wanted to use was strerror which takes errno as argument.