【问题标题】:"Cannot assign requested address" when binding to INADDR_LOOPBACK, but INADDR_ANY works绑定到 INADDR_LOOPBACK 时“无法分配请求的地址”,但 INADDR_ANY 有效
【发布时间】:2019-10-01 15:51:19
【问题描述】:

注意:我找到了正在研究这个问题的解决方案。下一个犯这个错误的人希望能在花太多时间之前发现这个问题。

我一直在尝试在 Linux 系统上实现 TCP 服务器。问题是我收到了一条非常笼统的错误消息,它没有揭示问题的原因:

$ 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 时它可以工作。我发现了一些有这个问题的问题,但反过来有点奇怪。

此错误消息的可能原因是什么?

【问题讨论】:

    标签: c linux tcp


    【解决方案1】:

    我一直在分配端口和地址错误:

    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代表“host to network short”,htonl代表“host to network long”,指的是地址和端口编码的字节顺序。

    INADDR_ANY 是地址0.0.0.0,这里字节顺序无关紧要。 INADDR_LOOPBACK 是地址127.0.0.1 被错误理解为1.0.0.127

    【讨论】:

      猜你喜欢
      • 2012-12-25
      • 2019-12-26
      • 1970-01-01
      • 2019-05-17
      • 2020-08-24
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多