«Невозможно назначить запрошенный адрес» при привязке к INADDR_LOOPBACK, но INADDR_ANY работает - PullRequest
1 голос
/ 01 октября 2019

Примечание: я нашел решение, которое исследует этот вопрос. Надеемся, что следующий, кто сделает эту ошибку, обнаружит этот вопрос, прежде чем уделить этому много времени.

Я пытался внедрить TCP-сервер в системе Linux. Проблема в том, что я получаю очень общее сообщение об ошибке, которое не раскрывает причину проблемы:

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

На этом сайте есть бесчисленное множество вопросов, описывающих подобную проблему, но ключДело в том, что это работает, когда я пытаюсь привязать к INADDR_ANY вместо INADDR_LOOPBACK. Я нашел несколько вопросов, которые имели эту проблему, но другой путь, который немного странный.

Каковы возможные причины этого сообщения об ошибке?

1 Ответ

2 голосов
/ 01 октября 2019

Я неправильно назначил порт и адрес:

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = 8080;
addr.sin_addr.s_addr = INADDR_LOOPBACK;

должно быть

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

htons означает "короткое соединение с сетью" и htonl означаетдля "host to network long" и ссылаются на порядок байтов, в котором кодируются адрес и порт.

INADDR_ANY - это адрес 0.0.0.0, порядок байтов здесь не имеет значения. INADDR_LOOPBACK - это адрес 127.0.0.1, который был неправильно понят как 1.0.0.127.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...