绑定失败:无法分配请求的地址。

8

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

每当我尝试将套接字绑定到固定IP(127.0.0.1或我的实际IP)时,就会出现“绑定失败:无法分配请求的地址”错误。 但是,当我将INADDR_ANY作为要绑定的地址传递给绑定函数时,它可以正常工作。

这是我唯一拥有的两个IP,因此不能因为我有其他可用的IP地址而使0.0.0.0起作用。

以下是代码:

#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 */
    }
}

我难道不是绑定了一个ip:port组合,而不仅仅是一个ip? netstat并没有显示端口1234被绑定到任何进程。 - ffledgling
1个回答

11

inet_addr函数返回网络字节序的地址:

inet_addr()函数将IPv4点分十进制表示法的Internet主机地址cp转换为二进制数据以网络字节序存储

因此可以去掉htonl函数。


我看到了新手错误。感谢您的快速回复! 当SO解除10分钟冷却期后,我会接受这个答案! - ffledgling
2
@Ayos:不,这不是新手错误。你只是没有仔细阅读文档。 - alk
太好了。那么htonl是用来做什么的?我在这里找到了另一个好的观察:https://www.lixu.ca/2014/09/c-implicit-declaration-of-function.html。“你应该避免使用它,而选择inet_aton()、inet_pton()或getaddrinfo()。” - Maf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接