Note: I found the solution which researching for this question. The next one making this mistake will hopefully discover this question before spending to much time on this.
I've been trying to implement a TCP server on a Linux system. The problem is that I receive a very generic error message that doesn't reveal the cause of the problem:
$ gcc -Wall -Wextra main.c
$ ./a.out
bind: Cannot assign requested address
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1) {
fprintf(stderr, "socket: %s\n", strerror(errno));
return EXIT_FAILURE;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = 8080;
addr.sin_addr.s_addr = INADDR_LOOPBACK;
if(bind(sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) {
fprintf(stderr, "bind: %s\n", strerror(errno));
return EXIT_FAILURE;
}
if(close(sockfd) != 0) {
fprintf(stderr, "close: %s\n", strerror(errno));
return EXIT_FAILURE;
}
}
There are countless questions on this site that describe a similar problem, but the key thing here is that it works when I try to bind to INADDR_ANY
instead of INADDR_LOOPBACK
. I found a few questions that had this issue, but the other way around which is a bit weird.
What are possible causes for this error message?
I've been assigning the port and address wrong:
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = 8080;
addr.sin_addr.s_addr = INADDR_LOOPBACK;
should be
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
htons
stands for "host to network short" and htonl
stands for "host to network long", and are refering to the byte order in which the address and port are encoded.
INADDR_ANY
is the address 0.0.0.0
, the byte order doesn't matter here. INADDR_LOOPBACK
is the address 127.0.0.1
which was incorrectly understood as 1.0.0.127
.