Reputation: 969
I am fairly new to socket programming. While programming a simple client-server application, I observed that we bind the server to the server address structure.
// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY; //focus on this line --- line 4
// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
As shown in the code, why do we require the line 4 ? We know the server socket is going to bind on the server machine-ip (itself), it can't bind to any other ip. What is the significance of INADDR_ANY
(or any other ip?) in this context?
Upvotes: 3
Views: 1010
Reputation: 193
It is to bind to all available interfaces in your machine/device. Explanation taken from here:
When you wrote your simple FTP server in project 1, you probably bound your listening socket to the special IP address INADDR_ANY. This allowed your program to work without knowing the IP address of the machine it was running on, or, in the case of a machine with multiple network interfaces, it allowed your server to receive packets destined to any of the interfaces. In reality, the semantics of INADDR_ANY are more complex and involved.
In the simulator, INADDR_ANY has the following semantics: When receiving, a socket bound to this address receives packets from all interfaces. For example, suppose that a host has interfaces 0, 1 and 2. If a UDP socket on this host is bound using INADDR_ANY and udp port 8000, then the socket will receive all packets for port 8000 that arrive on interfaces 0, 1, or 2. If a second socket attempts to Bind to port 8000 on interface 1, the Bind will fail since the first socket already ``owns'' that port/interface.
When sending, a socket bound with INADDR_ANY binds to the default IP address, which is that of the lowest-numbered interface.
Upvotes: 1
Reputation: 24738
A host machine can have more than one network interface installed (ie, connected to multiple networks at a time), and there is at least one IP address associated with each interface (consider, for example, IP aliasing).
INADDR_ANY
binds a socket to all available interfaces. Otherwise, you have to specify an IP address of a particuar interface to bind to.
Upvotes: 3
Reputation: 512
Now imagine a server. And the server has, say, 3 network cards. 1 is dedicated to production (dedicated to the application), another is for backups (so that during backups PROD NIC network would not get jammed) and the third one for maintenance (the one that has no access to outside world and is only used internally, for administrators to access the machine).
And you have a ssh daemon running inside. Now the server MUST NOT be accessible via ssh from outside world (i.e. from PROD NIC), so you cannot bind ssh to NIC1 IP and you cannot bind it to 0.0.0.0. NIC3 is dedicated for administrational purposes and you bind the ssh daemon to its IP.
Makes sense, doesn't it?
The same applies to backups and main app. Quite often the main app is not meant to be accessible from LAN hence it must be bound to NIC1 IP. And backups scheduler listener shall not be possible to be triggered by connections from outside, so you will bind it to IP of a NIC whichever is connected to bkups server (NIC2).
Usually local databases are bound to loopback ONLY so that they would not be accessible via any of the NICs. And general services are often available via any of the NICS installed on the server (think httpd, DNS @LAN, etc..)
That's why you have to bind -- you have to choose how will the socket be accessible: via loopback, via either of the NICs or via whatever NIC/LO.
Upvotes: 3