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