How does the socket API accept() function work?

Just to add to the answer given by user "17 of 26"

The socket actually consists of 5 tuple - (source ip, source port, destination ip, destination port, protocol). Here the protocol could TCP or UDP or any transport layer protocol. This protocol is identified in the packet from the 'protocol' field in the IP datagram.

Thus it is possible to have to different applications on the server communicating to to the same client on exactly the same 4-tuples but different in protocol field. For example

Apache at server side talking on (server1.com:880-client1:1234 on TCP) and World of Warcraft talking on (server1.com:880-client1:1234 on UDP)

Both the client and server will handle this as protocol field in the IP packet in both cases is different even if all the other 4 fields are same.


What confused me when I was learning this, was that the terms socket and port suggest that they are something physical, when in fact they're just data structures the kernel uses to abstract the details of networking.

As such, the data structures are implemented to be able to distinguish connections from different clients. As to how they're implemented, the answer is either a.) it doesn't matter, the purpose of the sockets API is precisely that the implementation shouldn't matter or b.) just have a look. Apart from the highly recommended Stevens books providing a detailed description of one implementation, check out the source in Linux or Solaris or one of the BSD's.


Your confusion lies in thinking that a socket is identified by Server IP : Server Port. When in actuality, sockets are uniquely identified by a quartet of information:

Client IP : Client Port and Server IP : Server Port

So while the Server IP and Server Port are constant in all accepted connections, the client side information is what allows it to keep track of where everything is going.

Example to clarify things:

Say we have a server at 192.168.1.1:80 and two clients, 10.0.0.1 and 10.0.0.2.

10.0.0.1 opens a connection on local port 1234 and connects to the server. Now the server has one socket identified as follows:

10.0.0.1:1234 - 192.168.1.1:80  

Now 10.0.0.2 opens a connection on local port 5678 and connects to the server. Now the server has two sockets identified as follows:

10.0.0.1:1234 - 192.168.1.1:80  
10.0.0.2:5678 - 192.168.1.1:80