Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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()?

share|improve this question

4 Answers 4

up vote 6 down vote accepted

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 10.11.12.13 (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

share|improve this answer
    
>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? –  Subi Suresh 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? –  Subi Suresh 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. ;-) –  Subi Suresh 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.

share|improve this answer
    
>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 –  Subi Suresh 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. –  Bruce Ediger 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? –  Subi Suresh May 7 '13 at 17:32
    
@SubiSuresh - I believe you wrote the truth. –  Bruce Ediger May 7 '13 at 19:48
    
>Thank u Bruce for verifying . –  Subi Suresh May 8 '13 at 2:47

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

share|improve this answer
    
@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 ? –  Subi Suresh May 7 '13 at 16:57

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

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.