As I understand it this is what happens when a client makes a connection request:

  1. The server will be bound to a particular port number. The port number is always bound to a listening process. Since only the server is listening for incoming connections, we don't need to bind on the client side
  2. The server will keep on listeninig on that port number.
  3. The client will send a connect() request.
  4. The server will accept the request using accept(). As soon as the server accepts the client request, the kernel allocates a random port number for the server for further send() and receive(), since the same port number on the server can't be used for sending as well as listening, and the previous port is still listening for new connections

Given all that, how does the server find out what port the client is receiving on? I know the client will send TCP segments with a source port and destination port, so the server will use the source port of that segment as its destination port, but what function does the server call to find out about that port? Is it accept()?


It's part of the TCP (or UDP, etc.) header, in the packet. So the server finds out because the client tells it. This is similar to how it finds out the client's IP address (which is part of the IP header).

E.g., every TCP packet includes an IP header (with source IP, destination IP, and protocol [TCP], at least). Then there is a TCP header (with source and destination port, plus more).

When the kernel receives a SYN packet (the start of a TCP connection) with a remote IP of (in the IP header) and a remote port of 12345 (in the TCP header), it then knows the remote IP and port. It sends back a SYN|ACK. If it gets an ACK back, the listen call returns a new socket, set up for that connection.

A TCP socket is uniquely identified by the four values (remote IP, local IP, remote port, local port). You can have multiple connections/sockets, as long as at least one of those differs.

Typically, the local port and local IP will be the same for all connections to a server process (e.g. all connections to sshd will be on local-ip:22). If one remote machine makes multiple connections, each one will use a different remote port. So everything but the remote port will be the same, but that's fine—only one of the four has to differ.

You can use, e.g., wirehsark to see the packet, and it'll label all the data for you. Here is the source port highlighted (notice it highlighted in the decoded packet, as well as the hex dump at the bottom):

Wireshark showing a TCP SYN packet

  • >Thanks for the explanation.So u meant to say that new server socket descriptor(ie tuple) obtained after the accept() will be having the client port and client address details and using that new socket descriptor server is sending and receiving the data to and from client.New socket file descriptor will be having a new server port number assigned by kernel,server ip,client ip and client port.Am i right? May 7 '13 at 17:21
  • @SubiSuresh yes, the tuple is stored inside the kernel, associated with that file descriptor.
    – derobert
    May 7 '13 at 17:21
  • >Thanks derobert.So i am concluding that new server socket descriptor will be having the client port and client address,which the server obtains from the accept().My understanding is fine right? May 7 '13 at 17:24
  • @SubiSuresh Yes, that's correct. From an application standpoint, you usually don't care (except for logging). The kernel makes sure the data you write (etc.) goes to the right place.
    – derobert
    May 7 '13 at 17:27
  • >thanks for your help and i think i got the point. ;-) May 7 '13 at 17:34

The "connect request (the client program's connect() system call, typically) causes a three-way handshake. The first packet of the 3-way handshake (from client to server) has the SYN flag set, and includes the TCP port number the client program's kernel assigns to it.

You can see this in an article on Nmap vs Natural SYN packets. The Nmap SYN packet decoding has the phrase "source.60058 > dest.22". The "legitimate SYN packet" decoding has the phrase "source.35970 > dest.80" in it. The two SYN packets tell the remote kernel that the packets are from TCP port 60058 and port 35970, respectively.

  • >But Bruce that is happening in the back end.But how my server is actually fetching the details like port number becuase normally in client server programs,i have never seen any function for fetching client port and client address May 7 '13 at 17:10
  • System call getpeername() should let you do that on any open socket. The accept() system call that the server code has to use to get a socket file descriptor to communicate back to the client has a parameter ("sockaddr" in my man pages) that contains the prospective client's IP address and TCP port number. May 7 '13 at 17:23
  • >Please dont mind if i elloborate.From all the inputs i got i understood that accept() is having the structure sockaddr_in filled with client details and the new server socket descriptor returned after the accept() will be automatically having client port and address.Thats why we are able to send using send(new server socket descriptor).I hope, am upto to the point ?This is just to make sure that what i have understood is right.Fine right? May 7 '13 at 17:32
  • @SubiSuresh - I believe you wrote the truth. May 7 '13 at 19:48

TCP socket is a stream-oriented socket. The two socket descriptors (owned by you and your peer) are reliably connected. So you don't have to worry about client's port -- just write your socket descriptor!

Also, feel free to getsockname(2) if you really want to know that (for logging maybe).


The connection is defined by a tuple (source IP, source port, destination IP, destination port). Answers go the reverse.

  • @vondrand That point i understood von .But from which function does the server comes to know about the client port number?With out knowing the client port number how it will send.So does server uses the structure in accept() to fetch the client port ? May 7 '13 at 16:57

Your Answer

