我在运行时出现错误:“无法分配请求的地址”;在Linux下的C语言中(Centos) [英] I got error in run time that "Cannot assign requested address" in C under Linux (Centos)

查看:409
本文介绍了我在运行时出现错误:“无法分配请求的地址”;在Linux下的C语言中(Centos)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我分配此地址时,它说无法分配请求的地址。但是,当我放置本地地址(127.0.0.1)时,它会接受它。为什么?

When I assign this address , it says cannot assign requested address. But when I put local address (127.0.0.1) it accepts it. Why???

char* hostname = "192.168.1.8"; 

int sockfd;
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
socklen_t addr_len;
int numbytes;
char buf[MAXBUFLEN];
int port =5000;

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    perror("socket");
    exit(1);
}
try
{
    my_addr.sin_family = AF_INET;        // host byte order
    my_addr.sin_addr.s_addr = inet_addr(hostname);

    printf("Accepted/n");
    // automatically fill with my IP
    my_addr.sin_port = htons(5000);  // short, network byte order
    memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct

    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
    {
        perror("bind");
        exit(1);
    }
    while (1)
    {
        addr_len = sizeof(struct sockaddr);
        if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
            (struct sockaddr *)&their_addr, &addr_len)) == -1) {
            perror("recvfrom");
            exit(1);
        }

        //printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
        //printf("packet is %d bytes long\n",numbytes);
        buf[numbytes] = '\0';
       //printf("packet contains \"%s\"\n",buf);
    }

    close(sockfd);
}
catch(...)
{


推荐答案

如果错误发生在 bind 上(根据您的问题内容,​​该错误并不明显,因为您指出的错误消息不会出现在代码),则可能是因为该地址不可用。

If the error is happening on the bind (it's not that obvious based on your question content since the error message you state does not appear in the code), it's likely to be because the address is not available.

通常是因为该地址已被使用,或者在当前主机上不可用。

That's usually because it's already in use, or not available on the current host.

除少数例外,您通常只能绑定到分配给本地接口的IP地址。您应该检查 192.168.1.8 在该类中。假设 127.0.0.1 将是本地接口(因此起作用),并且 INADDR_ANY 将起作用以及-可能是地址除非确实有特殊需要,否则就应该使用该接口。

With a few exceptions, you can generally only bind to IP addresses that are assigned to your local interfaces. You should check that 192.168.1.8 is in that class. It's a given that 127.0.0.1 will be a local interface (hence why it works), and that INADDR_ANY will work as well - that's probably the "address" you should use unless you have a real specific need to limit yourself to one interface.

您应该在失败的功能之后检查 errno 并将其与可能性进行匹配。

You should check the errno following the failing function and match it against the possibilities.

顺便说一句,这可能与您的问题无关,这是初始化 sockaddr_in 结构的方式(设置字段然后清除其余部分)

As an aside, and this is probably irrelevant to your problem, the way in which you initialise the sockaddr_in structure (setting fields then clearing the rest) seems to be less than portable to me.

我认为清除很多东西然后简单地设置您想要的东西会更安全,例如:

I think it would be safer to clear the lot then simply set what you desire after that, something like:

memset (&my_addr, 0, sizeof (my_addr));
my_addr.sin_family      = AF_INET;
my_addr.sin_addr.s_addr = inet_addr (hostname);
my_addr.sin_port        = htons (5000);

至少那样,结构中字段的顺序不会影响您的代码。

At least that way, the order of fields within the structure won't affect your code.

您可以使用以下代码查看问题。首先,必需的标头:

You can see the problem with the following code. First off, the requisite headers:

#define __USE_GNU
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

然后进行参数检查和套接字创建。

Then the argument checking and socket creation.

int main (int argc, char *argv[]) {
    int sockfd;
    struct sockaddr_in me;

    if (argc < 2) {
        printf ("Need argument with IP address\n");
        return 1;
    }

    if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        return 1;
    }

然后绑定本身:

    memset (&me, 0, sizeof (me));
    me.sin_family = AF_INET;
    me.sin_addr.s_addr = inet_addr (argv[1]);
    me.sin_port = htons (5000);

    if (bind (sockfd, (struct sockaddr *)&me, sizeof(struct sockaddr)) == -1)
    {
        fprintf (stderr, "errno = %d ", errno);
        perror("bind");
        exit(1);
    }

    close(sockfd);

    return 0;
}

使用某些参数运行该命令时,对于那些使用IP的人来说,它可以正常工作地址属于本地接口( 127.0.0.1 192.168.0.101 ),但不属于本地接口,例如 192.168.0.102

When you run that with certain arguments, you can see it works okay for the ones where the IP addresses belong to local interfaces (127.0.0.1 and 192.168.0.101) but not for those that do not, like 192.168.0.102:

pax> ifconfig | grep 'inet addr'
      inet addr:192.168.0.101  Bcast:192.168.0.255   Mask:255.255.255.0
      inet addr:127.0.0.1                            Mask:255.0.0.0
      inet addr:192.168.99.1   Bcast:192.168.99.255  Mask:255.255.255.0
      inet addr:192.168.72.1   Bcast:192.168.72.255  Mask:255.255.255.0

pax> ./testprog 127.0.0.1

pax> ./testprog 192.168.0.101

pax> ./testprog 192.168.0.102
errno = 99 bind: Cannot assign requested address

pax> grep '#define.*99' /usr/include/asm-generic/errno.h
#define     EADDRNOTAVAIL     99     /* Cannot assign requested address */

然后,从上面 bind 手册页的链接,我们看到:

And, from the link to the bind man page above, we see:


EADDRNOTAVAIL

请求的接口不存在或请求的地址不是本地地址。

EADDRNOTAVAIL
       A nonexistent interface was requested or the requested address was not local.

这篇关于我在运行时出现错误:“无法分配请求的地址”;在Linux下的C语言中(Centos)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆