I'm learning C socket programming. When would you use bind() on the client-side? What types of program will need it and why? Where can I find an example?
On the client side, you would only use bind if you want to use a specific client-side port, which is rare. Usually on the client, you specify the IP address and port of the server machine, and the OS will pick which port you will use. Generally you don't care, but in some cases, there may be a firewall on the client that only allows outgoing connections on certain port. In that case, you will need to bind to a specific port before the connection attempt will work.
An example would be the data connection of an active FTP connection. In this case, the server connects from its port 20 to the IP and port specified by a PORT or EPRT command.
A classic example of a client program using bind() is the (obsolete) rlogin / rsh family of network clients. These clients were intended to be used within networks with strong trust relationships - in some cases the server machine trusts the client machine to tell it the username of the user that is connecting. This required that the client program connect from a low port (a port less than 1024), because such ports are restricted to the root user and thus (in theory) prove that the client being used is authorised by the system administrator.
The NFS protocol has similar trust relationships, and similarly the client makes connections from a low port number, using bind().
Another example is IRC clients that allow the user to specify a particular source IP address to connect from. This is to accomodate users with many IP addresses assigned to their machine, each with a different "vanity" domain name assigned to it. Choosing which IP to connect from (with bind()) allows the user to choose which domain name to appear as on IRC.
A good situation would be in a p2p case, you’re communicating with a STUN Server with a bound socket, and the STUN Server tells you the port on which he is receiving messages from your socket (that can be different from the one you specified when you bound your socket depending on your network and more specifically on your NAT type). This will allow you to be aware of the real port translation that your NAT is doing, and you’ll be able to give this information to potential peers that want to connect to you.
Binding the socket is useful as some NATs are dynamically giving you ports (binding on port x twice might not give you the same “real” port). So you’ll be able to directly use the socket you bound to listen on the port.
I suppose you should bind() in the case of UDP sockets.
bind function is one of "key" functions. It associates your socket (server or client) with address (ip + port). As for Windows you must use bind for WinSockets. There is good book about it "Network Programming for Microsoft Windows" by Anthony Jones and Jim Ohlund.
Bind can be used to attach names to a sockets. Thus, say you create a software that uses a particular TCP port, you need to bind it and then, you will know the TCP port it is using.
Related
There's already a question How exactly does a remote program like team viewer work which gives a basic description, but I'm interested in how the comms works once the client has registered with the server. If the client is behind a NAT then it won't have its own IP address so how can the server (or another client) send a message to it? Or does the client just keep polling the server to see if its got any requests?
Are there any open source equivalents of LogMeIn or TeamViewer?
The simplest and most reliable way (although not always the most efficient) is to have each client make an outgoing TCP connection to a well-known server somewhere and keep that connection open. As long as the TCP connection is open, data can pass over that TCP connection in either direction at any time. It appears that both LogMeIn and TeamViewer use this method, at least as a fall-back. The main drawbacks for this technique are that all data has to pass through a TeamViewer/LogMeIn company server (which can become a bottleneck), and that TCP doesn't handle dropped packets very well -- it will stall and wait for the dropped packets to be resent, rather than giving up on them and sending newer data instead.
The other technique that they can sometimes use (in order to get better performance) is UDP hole-punching. That technique relies on the fact that many firewalls will accept incoming UDP packets from remote hosts that the firewalled-host has recently sent an outgoing UDP packet to. Given that, the TeamViewer/LogMeIn company's server can tell both clients to send an outgoing packet to the IP address of the other client's firewall, and after that (hopefully) each firewall will accept UDP packets from the other client's Internet-facing IP address. This doesn't always work, though, since different firewalls work in different ways and may not include the aforementioned UDP-allowing logic.
Ok, so I understand that communication between a client computer and a server computer can be initiated in windows with the creation of a socket between the two computers, but every tutorial that I have seen depends on the End User knowing the IP address of the computer that they wish to connect to.
In local network LAN games, however, the clients somehow autodetect the server. How is this done? Does the client autocheck every possible IP, is there some sort of "GetDetectedIPs" api, etc?
Im looking for answers that can be implemented in standard WIN32 API in straight C. No MFC, .NET, or C++ please. Thank you.
The technique you need is called broadcasting. It's used, for example, in BOOTP and DHCP protocols.
Sending a packet with broadcast destination address results in it being received by all devices in LAN. Broadcast address is an IP address in which the host identification field is filled with ones:
bcast_addr = ~netmask | my_addr;
The discovery process is usually like follows:
The client sends a UDP datagram with broadcast destination address at specific port.
The server listens on this port and receives the datagram. Other computers discard it.
Server sends all the necessary info about itself to the client by a usual UDP datagram.
This is usually done with zero-conf. Microsoft version of it is Simple Service Discovery Protocol.
You could just let the client send an UDP packet to every IP in a specified range and let the server answer with another UDP packet.
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...
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.
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.
im new to linux environment and any help/feedback would be appreciated. Im actually trying to develop a client-server (MULTICAST) program, so, i would like to test one client sending information to different servers (one-to-many relationship). thus, i would like to simulate different server side in linux with different IP addresses in one computer.
Did you try using different ports instead? I didn't try it myself, but perhaps that can help you in the mid-time.
If you're really multicasting, you don't need to worry about physical host-specific IP:s, all you should need to do is make sure all the programs (clients and servers) are using the same multicast group addresses. Then they should all see each other's traffic automatically.
There's nothing stopping you from running multiple clients on the same machine that also runs the server, in this case.
I sounds like you want to test your code with different IP's. You can create IP aliases on your interface and simulate multiple IP's on one computer.
for e.g. if eth0 is you're active interface with IP, say 192.168.5.11 you can assign another IP to eth0:0 (an alias to eth0) as below.
ifconfig eth0:0 192.168.5.12 netmask255.255.255.0 up
ifconfig eth0:1 192.168.5.13 netmask255.255.255.0 up
run your server on one of the IP's and distribute clients to all your aliases
Use either of the following when you do not have sufficient hardware:
Multicast loop which has the IP stack redirect outbound packets to local receivers.
Virtual machines.
Be aware that semantics of the socket option for #1 change depending on the operating system; for #2 only some virtual machines support multicast, refer to the vendor for details.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms739161(v=vs.85).aspx
Ultimately though you must test with different machines due to specific artifacts of how hosts manage multicast groups. You can for instance create send-only membership which will block every other application on the host. Also consider that an internet, lower case 'I', will introduce further artifacts regarding group joining and propagation delays and drops that your application may need to be aware of.
You can create multiple IP for same machine with help of IP alias. As mentioned above.
But to create multiple Server at one PC you must need different port for each server if you want to simulate the all server behavior with network as well.
I mean for one port multicast traffic always goes to that and some process in the PC will be receiving the packet and has to serve for all server in the PC, Means you have one packet only and all server is receiving with locally manipulation.
But really simulation would be you have multiple server at 1 PC and all are receiving multicast traffic from network rather then from local process.
my Solution: You keep number for server == number of port at the PC. Client send the multicast traffic over all port simultaneously and all server at the PC end will be receiving multicast packet from corresponding port from the Network.
Please correct me if my understanding is wrong.
The Tcp server need to serve many clients, If one client one server port and one server thread to listen the port, I want to know weather it is faster ?
If one port is good, could someone explain the different between one port and multiple ports in this case, thanks!
The problem with using multiple ports to achieve this is that each of your clients will each have a specific port number. Depending on the number of clients there could be a tremendous amount of bookkeeping involved.
Typically, for a tcp server that is to serve multiple clients, you have a "main" thread which listens to a port and accepts connections on that port. That thread then passes the connected socket off to another thread for processing and goes back to listening.
For a wealth of Unix network programming knowledge check out "The Stevens Book"
Generally speaking* the server will allocate it's own outgoing sockets for each connected client (and you don't need to be aware of those numbers). Each client connection handle will hold it's port references.
When defining the servers connection port, you will allocate a socket for incoming clients to connect to. There is no performance benefit using multiple sockets, in fact allocating additional sockets will show a performance hit (although for each port it will be tiny.)
update...
By the way, assigning multiple incoming ports (particularly a large range) for clients to connect to is also insane. From the perspective of making the service usable and maintainable.