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

查看:24
本文介绍了我在运行时遇到“无法分配请求的地址"错误.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), '', 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
",inet_ntoa(their_addr.sin_addr));
        //printf("packet is %d bytes long
",numbytes);
        buf[numbytes] = '';
       //printf("packet contains "%s"
",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
");
        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.1192.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天全站免登陆