C语言 绑定失败:无法分配请求的地址

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15488092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:46:11  来源:igfitidea点击:

bind failed: Cannot assign requested address

csockets

提问by ffledgling

I'm trying to write a C program that listens on a port on my machine. I'm running into a strange error.

我正在尝试编写一个 C 程序来侦听我机器上的一个端口。我遇到了一个奇怪的错误。

Whenever I try to bind the socket to a fixed ip (either 127.0.0.1or my actual IP) I get a "bind failed: Cannot assign requested address"error. However when I pass INADDR_ANYto the bind as the address to bind to, it works.

每当我尝试将套接字绑定到固定 IP(127.0.0.1或我的实际 IP)时,我都会收到"bind failed: Cannot assign requested address"错误消息。但是,当我将INADDR_ANY绑定作为要绑定到的地址传递给它时,它会起作用。

These are the only two IPs I have so it can't be that the 0.0.0.0 works because of some other IP address I have available.

这是我仅有的两个 IP,因此 0.0.0.0 不能工作,因为我有其他一些可用的 IP 地址。

Here is the code:

这是代码:

#include<sys/types.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    int port = 1234;    /* port number */
    int rqst;       /* socket accepting the request */
    socklen_t alen;       /* length of address structure */
    struct sockaddr_in my_addr;    /* address of this service */
    struct sockaddr_in client_addr;  /* client's address */
    int sockoptval = 1;

    int svc;


    /* create a TCP/IP socket */
    if ((svc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("cannot create socket");
        exit(1);
    }

    /* allow immediate reuse of the port */
    setsockopt(svc, SOL_SOCKET, SO_REUSEADDR, &sockoptval, sizeof(int));

    /* bind the socket to our source address */
    memset((char*)&my_addr, 0, sizeof(my_addr));  /* 0 out the structure */
    my_addr.sin_family = AF_INET;   /* address family */
    my_addr.sin_port = htons(port);
    //my_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Works! */
    my_addr.sin_addr.s_addr = htonl(inet_addr("127.0.0.1")); /* Fails! */

    if (bind(svc, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) {
        perror("bind failed");
        exit(1);
    }

    printf("Listening on %d\n", my_addr.sin_addr.s_addr);
    /* set the socket for listening (queue backlog of 5) */
    if (listen(svc, 5) < 0) {
        perror("listen failed");
        exit(1);
    }

    /* loop, accepting connection requests */
    for (;;) {
        while ((rqst = accept(svc, (struct sockaddr *)&client_addr, &alen)) < 0) {
            /* we may break out of accept if the system call */
                        /* was interrupted. In this case, loop back and */
                        /* try again */
                        if ((errno != ECHILD) && (errno != ERESTART) && (errno != EINTR)) {
                                perror("accept failed");
                                exit(1);
                        }
                }
        /* the socket for this accepted connection is rqst */
    }
}

回答by cnicutar

The function inet_addrreturns the address already in network order:

该函数inet_addr返回已按网络顺序排列的地址:

The inet_addr() function converts the Internet host address cp from IPv4 numbers-and-dots notation into binary data in network byte order

inet_addr() 函数将 Internet 主机地址 cp 从 IPv4 数字和点表示法转换为网络字节顺序的二进制数据

So drop the htonl.

所以放下htonl.