Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I got error in run time that "Cannot assign requested address" in C under Linux (Centos)

Tags:

c

linux

centos

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(...)
{
like image 606
gaurav bhadani Avatar asked Jan 10 '12 06:01

gaurav bhadani


People also ask

What (): bind Cannot assign requested address?

The message “Cannot assign requested address” suggests that the hostname/IP you are trying to bind does not resolve to a local network interface. A few things to check: Are the full hostnames (eg 01.mongodb.DOMAIN.nl ) resolvable on all of your replica set members?

What does Cannot assign requested address mean?

10.18 'Network error: Cannot assign requested address' This means that the operating system rejected the parameters of the network connection PuTTY tried to make, usually without actually trying to connect to anything, because they were simply invalid.

Can't assign requested address nested exception is Java net Bindexception Cannot assign requested address?

There are some different possible causes for this problem. One is that the local (loopback) socket configuration has been removed from the IP configuration for the system that is logging this message. Another possible cause is that the default IP configuration for the JVM is IPv6 and the IP address is in IPv4 format.


1 Answers

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.

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.

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


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;
    }

Then the binding itself:

    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;
}

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

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

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

like image 108
paxdiablo Avatar answered Oct 16 '22 19:10

paxdiablo