114

I am trying to program some sockets and so, on the server side, I use htonl(INADDR_ANY). To the extent I understood, it seems to me that this function generates a random IP (am I correct ?). In fact, I want to bind my socket with my localhost. But if I run this

printf("%d",htonl(INADDR_ANY));

I get 0 as a return value. Could someone bring some explanation ?

jww
  • 97,681
  • 90
  • 411
  • 885
epsilones
  • 11,279
  • 21
  • 61
  • 85
  • 14
    "*... I use `htonl(INADDR_ANY)`. The doc says that this function generates a random IP ...*" This is not correct. Which docs tells you so? – alk May 12 '13 at 15:06
  • 2
    @alk, in fact I mislead : I was reading some pdf I thought to be some official documentation. I edit my post now – epsilones May 12 '13 at 20:06

7 Answers7

187
  1. bind() of INADDR_ANY does NOT "generate a random IP". It binds the socket to all available interfaces.

  2. For a server, you typically want to bind to all interfaces - not just "localhost".

  3. If you wish to bind your socket to localhost only, the syntax would be my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");, then call bind(my_socket, (SOCKADDR *) &my_sockaddr, ...).

  4. As it happens, INADDR_ANY is a constant that happens to equal "zero":

    http://www.castaglia.org/proftpd/doc/devel-guide/src/include/inet.h.html

    # define INADDR_ANY ((unsigned long int) 0x00000000)
    ...
    # define INADDR_NONE    0xffffffff
    ...
    # define INPORT_ANY 0
    ...
    
  5. If you're not already familiar with it, I urge you to check out Beej's Guide to Sockets Programming:

    http://beej.us/guide/bgnet/

Since people are still reading this, an additional note:

man (7) ip:

When a process wants to receive new incoming packets or connections, it should bind a socket to a local interface address using bind(2).

In this case, only one IP socket may be bound to any given local (address, port) pair. When INADDR_ANY is specified in the bind call, the socket will be bound to all local interfaces.

When listen(2) is called on an unbound socket, the socket is automatically bound to a random free port with the local address set to INADDR_ANY.

When connect(2) is called on an unbound socket, the socket is automatically bound to a random free port or to a usable shared port with the local address set to INADDR_ANY...

There are several special addresses: INADDR_LOOPBACK (127.0.0.1) always refers to the local host via the loopback device; INADDR_ANY (0.0.0.0) means any address for binding...

Also:

bind() — Bind a name to a socket:

If the (sin_addr.s_addr) field is set to the constant INADDR_ANY, as defined in netinet/in.h, the caller is requesting that the socket be bound to all network interfaces on the host. Subsequently, UDP packets and TCP connections from all interfaces (which match the bound name) are routed to the application. This becomes important when a server offers a service to multiple networks. By leaving the address unspecified, the server can accept all UDP packets and TCP connection requests made for its port, regardless of the network interface on which the requests arrived.

nbro
  • 15,395
  • 32
  • 113
  • 196
paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • 9
    It doesn't mean 'bind to all interfaces'. If it did that, the netstat output would be different. It means 'listen at *any* interface'. – user207421 May 12 '13 at 22:09
  • 8
    To quote the above link: "When INADDR_ANY is specified in the bind call, the socket will be bound to all local interfaces." From another link: [The value "INADDR_ANY" means that we will bind to any/all IP addresses that the local computer currently has](http://www.scottklement.com/rpg/socktut/bindapi.html). But yes - many implementions will bind to *the first* interface, (not "all"). But for one PC with one NIC, the difference is academic. With INADDR_ANY, the client can connect to any/all IP's (e.g. both 192.168.1.2 and 127.0.0.1). – paulsm4 May 13 '13 at 03:40
  • Is it guaranteed to equal 0? – David G Mar 06 '15 at 14:33
  • 7
    Sorry if this is a stupid question, but does interface mean wireless, ethernet, etc? – mrQWERTY Mar 18 '15 at 03:36
  • When will people need to bind to `127.0.0.1` instead of `0.0.0.0`? – laike9m Sep 15 '15 at 14:21
  • 3
    @laike9m You'd bind to 127.0.0.1 when you want to be able to connect to the socket only from the local machine. There are use cases for this when the service offered by the socket is only intended to be used by another process that is local to the machine. – dgnuff Oct 08 '15 at 22:29
  • @dgnuff Why is that binding to 127.0.0.1 prevents sockets connecting from other machine? Though I know 127.0.0.1 is the local address, I just don't understand the logic, or is this documented somewhere? – laike9m Oct 09 '15 at 01:38
  • @laike9m: another name for this address is "loopback interface" - when you send, it "loops back" to the same host, without ever actually touching any network hardware. Here are more details: [What is the loopback device and how do I use it?](http://askubuntu.com/questions/247625/what-is-the-loopback-device-and-how-do-i-use-it) – paulsm4 Oct 09 '15 at 05:49
  • 2
    @paulsm4 In 3, can't you use `INADDR_LOOPBACK`, instead of `inet_addr("127.0.0.1")` ? – John Strood Oct 30 '16 at 09:54
  • @paulsm4 Also, when you use `LOOPBACK` for `sin_addr.s_addr` in a server application, does it mean client applications from other hosts cannot connect to it? – John Strood Oct 30 '16 at 10:08
72

INADDR_ANY is used when you don't need to bind a socket to a specific IP. When you use this value as the address when calling bind(), the socket accepts connections to all the IPs of the machine.

Barmar
  • 741,623
  • 53
  • 500
  • 612
13

To bind socket with localhost, before you invoke the bind function, sin_addr.s_addr field of the sockaddr_in structure should be set properly. The proper value can be obtained either by

my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1")

or by

my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
MichaelGoren
  • 961
  • 9
  • 15
9

INADDR_ANY instructs listening socket to bind to all available interfaces. It's the same as trying to bind to inet_addr("0.0.0.0"). For completeness I'll also mention that there is also IN6ADDR_ANY_INIT for IPv6 and it's the same as trying to bind to :: address for IPv6 socket.

#include <netinet/in.h>

struct in6_addr addr = IN6ADDR_ANY_INIT;

Also, note that when you bind IPv6 socket to IN6ADDR_ANY_INIT your socket will bind to all IPv6 interfaces, and should be able to accept connections from IPv4 clients as well (though IPv6-mapped addresses).

Pavel P
  • 15,789
  • 11
  • 79
  • 128
6

When you have a server, you create a socket and then you bind it to an IP and port, which gives the socket a unique way to be identified based on a unique socket type, address family, IP and port. You then listen() to set the socket to server mode, and then you do accept(), which waits on a connection which will have inbound packets with target IP/port that cause the packets to be queued on that socket. You don't need to bind it to an IP however, it can accept connections on all interfaces.

When you have a client, you create a socket, and then you connect() the socket to a remote IP and port, which will also bind 0.0.0.0 and a random unused ephemeral port to the socket if it hasn't been already bound to an IP and port using bind(INADDR_ANY, 0). connect() returns when it connects, and uses the IP and port as the source address in the outbound packets, where 0.0.0.0 is always substituted with an IP based on src hint in the routing table or the IP of the selected interface (if it has multiple IPs then first IP with same or bigger scope is selected), and then you use sendall to send application data.

INADDR_ANY is faster than programmatically acquiring the current internal IP of the interface, which could change at any moment, and packets will no longer be received on the port, but they'd still be received on 0.0.0.0 because it is any address.

Note that a socket can be bound to 0.0.0.0, but not port 0, because its a wildcard that makes it give the socket a random ephemeral port, so when you use bind(INADDR_ANY, 0) it binds to 0.0.0.0 and a random ephemeral port.

Lewis Kelsey
  • 4,129
  • 1
  • 32
  • 42
3

INADDR_ANY is a constant, that contain 0 in value . this will used only when you want connect from all active ports you don't care about ip-add . so if you want connect any particular ip you should mention like as my_sockaddress.sin_addr.s_addr = inet_addr("192.168.78.2")

vivek
  • 101
  • 1
  • 2
0
#include <arpa/inet.h>                                                                     
.                                                                                   
.                                                                                        
tcpsock.sin_addr.s_addr = inet_addr("192.168.1.2")

worked for me

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Anish T
  • 71
  • 1
  • 3