Reputation: 271
While I was reading how to make a TCP client/server connection in C, I had a doubt about the bind() function.
I read that you need this function to "bind" a socket you've created to a local IPEndPoint, because the client/server connection takes a socket pair, made by LocalIP:LocalPort, RemoteIP:RemotePort. Thus my questions are:
What happens and what does the kernel do when a client doesn't call bind(), but calls connect() immediately after creating a socket (this is a common thing; I do it too in a client program, but I don't understand why I needn't to bind)?
... and above all ...
Why does a server program call bind(), specifying INADDR_ANY as the LocalIP address? I read that this constant is useful to specify a generic IP address, that is the server accepts data from anywhere on the Internet. But... is this a specification of a local IP address, or does it indicates where the clients can reach the server? I'm getting very confused...
Upvotes: 5
Views: 5685
Reputation: 2966
1) You usually only need to call Bind if you want to create a server socket. There are some cases where it is required to establish a client socket, but more often than not, it is not necessary for for a client sockets. If you want to wait for incoming connections on a certain port, you have to bind to it. If you want to connect out to some IP and Port, there's no need to bind. The server socket's bind takes exclusive access to the TCP port. Nothing else can come online and bind to that port until your application closes or the socket is closed by you.
2) You are specifying which IP on the local computer to bind to. A single computer can have many IP addresses. Your computer may have a wired and wireless connection. Each has its own IP on the local network. You can specifically bind to one of those IPs and not the other. You could even have one application bound to port 473 (for example) on one IP and an entirely different application bound to port 473 on the other IP. If you specify INADDR_ANY, you are binding to all valid IPs the machine has. So it doesn't matter what IP the client used to get to you, it will work.
Upvotes: 4
Reputation:
What happens and what does the kernel do when a client doesn't call bind(), but calls connect() immediately after creating a socket (this is a common thing; I do it too in a client program, but I don't understand why I needn't to bind)?
When you make an outbound connection without first binding the socket to an IP/port, the kernel will pick a source IP and port automatically, based on routing tables and what ports are available.
Why does a server program call bind(), specifying INADDR_ANY as the LocalIP address? I read that this constant is useful to specify a generic IP address, that is the server accepts data from anywhere on the Internet. But... is this a specification of a local IP address, or does it indicates where the clients can reach the server? I'm getting very confused...
What you've read is inaccurate -- the IP address in the sockaddr passed to bind()
doesn't indicate where the server will accept connections from. It indicates what local IP addresses the socket should be attached to. INADDR_ANY indicates that you want to listen for connections on the specified port on any and all IP addresses attached to the machine. On servers with multiple IP addresses, it's often useful to specify one IP address to bind()
to, so that other sockets can be bound to the same port on other IPs. It's also often useful to bind to a port on localhost only.
Upvotes: 4