getsockname always returning 0.0.0.0?

2019-03-12 20:01发布

Here is the code. It is the same as the code from this similar question: http://monkey.org/freebsd/archive/freebsd-stable/200401/msg00032.html. When I run it I always get the output:

listening on 0.0.0.0:54493 or something. Obviously the port changes, but I have no idea why I keep getting an IP address of 0.0.0.0. Am I missing something?

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    int sock;
    int len = sizeof(struct sockaddr);
    struct sockaddr_in addr, foo;

    if((sock=socket(AF_INET, SOCK_STREAM, 0))<0)
    {
        exit(0);
    }

    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(0);

    if(bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))<0)
    {
        perror("bind");
        exit(0);
    }

    if(listen(sock, 5)<0)
    {
         perror("listen");
         exit(0);
    }

    getsockname(sock, (struct sockaddr *) &foo, &len);
    fprintf(stderr, "listening on %s:%d\n", inet_ntoa(foo.sin_addr), 
            ntohs(foo.sin_port));

    return 0;
}

3条回答
爷的心禁止访问
2楼-- · 2019-03-12 20:13

Yes, if you bind it to a LOOPBACK , u have to specify INADDR_LOOPBACK. Otherwise it attaches itself to 0.0.0.0 which represents all the network interfaces available. I was facing the same problem, while issuing getnameinfo() call.

查看更多
一夜七次
3楼-- · 2019-03-12 20:25

You specify INADDR_ANY rather than a specific IP address, so it binds to the wildcard (all interfaces) 0.0.0.0. So, when you call getsockname() that's what you get back.

If you specified 0.0.0.0 as the IP address rather than INADDR_ANY you would get the same behavior; you will bind to all network interfaces on the machine.

For example, lets say you only have one network interface with the IP 192.168.1.12 assigned to it. You also have the loopback by default - 127.0.0.1

Using 0.0.0.0 or INADDR_ANY means you'll be bound to both those addresses, rather than a specific one. You will be able to connect to to your process via either IP.

If you were to bind to a specific IP rather than INADDR_ANY, your process would only listen on that IP and you'd get back that specific IP with getsockname().

查看更多
何必那么认真
4楼-- · 2019-03-12 20:25

As mentioned in the other answers, 0.0.0.0 is returned because INADDR_ANY was specified as the host address for the listening socket. This makes sense if you think that, in a multi-homed host, client connections could come in on any of those interfaces (so which should be reported?)

Expanding on those answers; if the actual IP address of a client connection is required, use the SOCKET returned from accept() with getsockname(). This will provide the interface address on the server to which the client connected.

查看更多
登录 后发表回答