I am confused regarding the sockets. As far as I know socket is combination of ip address and port number. Its just programming abstraction to allow to write to, or read from a stream (in case of TCP). Now what I am not absolutely sure of, is whether the server has ONE or MORE sockets when serving the client? Lets say http
at port 80.
Does all data from various clients got sent to one socket (server:80) and some UBER server process distinguishes them based on incoming address or are more sockets based on combination of client address and port number created by TCP layer?. Can someone describe this thoroughly with step-by-step algorithm (for multiple clients served at the same time) and not just with Server binds socket to port, Server listens to socket, Server serves data.
You're confusing TCP connections with sockets. A socket is not a network-level concept. Is is an OS concept. A TCP connection exists on the network as a unique combination of (source-ip, source-port, dest-ip, dest-port). A socket is a handle to an open port or an open connection (this statement is slightly simplified). When I got started I also thought this was confusing and an OS design error (but it is what it is and we are stuck with it). The design error is that the allowed operation for each of the different sockets are very much different. These use cases should have been two independent concepts with different names and different APIs.
As you can see there is no 1:1 relationship between sockets and connections.
Can someone describe this thoroughly with step-by-step algorithm
A server opens a socket to let the OS know that it wants to listen or connect. Then, every accepted connection will result in a new, independent socket. Every new connection is on the same server-ip and server-port though. Just the client-ip and/or client-port are different. The server reads and writes on the per-connection sockets. The open-port socket is just for accepting new connections.
The server conceptually goes like this:
var openPortSocket = Open(80); //HTTP port
while(true) {
var connectionSocket = openPortSocket.Accept();
ServeConnectionOnNewThread(connectionSocket);
}
This is a logical model. The actual API calls are different. Most servers use async IO for example. That is not relevant to your question though.
Clients must use a different client port for each connection. This is exactly what your browser does.
Usually, on the server side, after the socket is created and bound to a particular port/address combination, a function called Listen
(or similar) will be called. This makes this bound socket a listening socket - it's just waiting for connection attempts to start.
After this, there will be a call to a function called something like Accept
on the listening socket. This call will take a pending connection request from the listening socket, create a new socket, and return that.
All further communication between the client and the server will be via this new socket (at the server end), for the duration of the connection.
Different techniques may be used to achieve scalability if the server needs to be handling multiple client connections simultaneously. One simple technique (which doesn't scale to thousands of connected clients) is to spawn a new thread/process (depending on what's cheap on your O/S) to hand this connection and then the original thread/process returns to calling Accept
.
Other techniques may involving placing the socket in some form of pool or being able to have sockets generate events which are processed by a fixed number of threads, as and when each socket needs attention.
I can speak mostly to Linux, although I believe most OS/kernels operate similarly. The short answer is that the kernel does most of the work.
The kernel communicates with some sort of network interface, which basically is just translating signals from the wire to the kernel and vice versa. Sockets and addresses are merely descriptors of a given connection. The kernel keeps track of what internal processes are related to which socket/address pairs and it will direct data accordingly. Generally, this is implemented as a FIFO -- first in, first out. This is true for incoming and outgoing data.
If a server is connected to multiple clients, usually it is the responsibility of the application to send out separate packets to each of the connected clients, which means that the application has to keep track of the number of active clients. Some kernels and/or NICs can do some of this for you. If this is a local network and you want to send packets to every client connected to the network, you can send broadcast packets, which only must be sent once but every connection will receive.
If you want a lot more information, this link is very thorough:
What is the difference between a port and a socket?