c - 绑定(bind)到 INADDR_LOOPBACK 时为 "Cannot assign requested address",但 INADDR_ANY 有效

标签 c linux tcp

注意:我找到了研究这个问题的解决方案。下一个犯这个错误的人有望在花费大量时间之前发现这个问题。

我一直在尝试在 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;
    }
}

这个网站上有无数的问题描述了类似的问题,但这里的关键是当我尝试绑定(bind)到 INADDR_ANY 而不是 INADDR_LOOPBACK 时它起作用了。我发现了几个有这个问题的问题,但反过来有点奇怪。

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

最佳答案

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

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

关于c - 绑定(bind)到 INADDR_LOOPBACK 时为 "Cannot assign requested address",但 INADDR_ANY 有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58188415/

相关文章:

python - 将变量发送到python中的TCPHandler

c++ - 打印所有线程的堆栈跟踪而不附加 GDB

c - AF_UNIX 套接字 : select() firing when there is nothing to read

我可以检查指针是否由 malloc/calloc/realloc 分配吗?

linux - 使用 putty 启动 JBOSS

C# 查找进行 UDP/TCP 调用的客户端的进程 ID (pid)

c++ - g++ 没有 gcc 也能工作吗?

ruby-on-rails - 目录 : $bundle install =>/usr/bin/env: ruby: not a directory

linux - 更改了键盘布局,现在无法再登录,因为 Linux 上缺少字母

c++ - Boost 连接后从 TCP 服务器访问 TCP 客户端 IP 地址 + 端口