network programming: how does s.accept() work?

Grant Edwards grante at
Mon Feb 25 23:31:58 CET 2008

On 2008-02-25, 7stud <bbxx789_05ss at> wrote:
> On Feb 25, 10:56 am, Thomas Bellman <bell... at> wrote:
>> 7stud <bbxx789_0... at> wrote:
>> > The question I'm really trying to answer is: if a client connects to a
>> > host at a specific port, but the server changes the port when it
>> > creates a new socket with accept(), how does data sent by the client
>> > arrive at the correct port?  Won't the client be sending data to the
>> > original port e.g. port 5052 in the client code above?
>> The answer is that the server *doesn't* change its port.  As you
>> could see in the output of your server, the socket that accept()
>> returned also had local port 5052.  Each *client* will however
>> get a unique local port at *its* end.
>> A TCP connection is identified by a four-tuple:
>>     ( localaddr, localport, remoteaddr, remoteport )
>> Note that what is local and what is remote is relative to which
>> process you are looking from.  If the four-tuple for a specific
>> TCP connection is (, 5052,, 50816 ) in your
>> server, it will be (, 50816,, 5052 ) in the
>> client for the very same TCP connection.
>> Since your client hasn't bound its socket to a specific port, the
>> kernel will chose a local port for you when you do a connect().
>> The chosen port will be more or less random, but it will make
>> sure that the four-tuple identifying the TCP connection will be
>> unique.

> But your claim that the server doesn't change its port flies in the
> face of every description I've read about TCP connections and
> accept().

Then the descriptions are wrong.

> The articles and books I've read all claim that the server
> port 5053 is a 'listening' port only.

Not true.

> Thereafter, when a client sends a request for a connection to
> the listening port, the accept() call on the server creates a
> new socket for communication between the client and server,

True.  But, it doesn't change the local port number.  

Both the listing socket and the connected socket are using
local port number 5053.

> and then the server goes back to listening on the original
> socket.

That's true.

> I would expect the reported ip address to be ''.
> Also, since a socket is uniquely identified by an ip address
> and port number,

It isn't.

1) You seem to be conflating sockets and TCP connections.  A
   socket is a kernel-space data structure used to provide a
   user-space API to the network stack.  In user-space it's
   identified by an integer index into a per-process table of
   file-like-objects.  That socket may or may not have a TCP
   connection associated with it.  It may or may not be bound
   to an IP address and/or port.  It is not uniquely identified
   by an IP address and port number.

2) A tcp connection is a _different_ thing (though it also
   corresponds to a kernel-space data structure), and as Thomas
   said, it is uniquely identified by the a four-tuple:

     (localaddr, localport, remoteaddr, remoteport)

   [Technically, it's probably a 5-tuple with the above
   elements along with a 'connection type' element, but since
   we're only discussing TCP in this thread, we can ignore the
   connection type axis and only consider the 4-axis space of
   TCP connections.]
   When a second client connects to the server on port 5053,
   the first two elements in the tuple will be the same.  One
   or both of the last two elements will be different.
> then the ('', 5053) socket is not the same as this
> socket:
> new socket, self: ('', 5053)

Referring to sockets using that notation doesn't really make
sense.  There can be more than one socket associated with the
local address ('', 5053) or to any other ip/port tuple
you'd like to pick.

Grant Edwards                   grante             Yow! YOU PICKED KARL
                                  at               MALDEN'S NOSE!!

More information about the Python-list mailing list