[Twisted-Python] TCP: can't redo connectTCP() from same local port if server did not explicitly close connection ??
exarkun at divmod.com
Thu Jan 15 07:58:06 EST 2009
On Thu, 15 Jan 2009 11:44:44 +0100, Alessio Pace <alessio.pace at gmail.com> wrote:
>I would like to have a client connect via TCP to a server (say, server "A"),
>then the client close the connection and connect via TCP to another server
>(say, server "B") using the same TCP port that was bound locally while
>connecting to "A". And then this done over and over again switching from B
>to A to B etc..
>The fact is that it all works if both the client and the server do
>transport.loseConnection() before the client tries to connect to the other
>server from the same local port, instead if *only* the client does
>transport.loseConnection(), I obtain:
>[Failure instance: Traceback (failure with no frames): <class
>> 'twisted.internet.error.ConnectBindError'>: Couldn't bind: 98: Address
>> already in use.
>which it is strange to me as the next connectTCP() attempt is called in the
>connectionLost() method of the client, so the socket should be closed
This is because the client connection goes into the CLOSE_WAIT state instead
of really closing all the way right away. Google for "tcp state diagram"
and take a look at how a socket can close - notice that of the two paths
there are to get to CLOSED, only one of them goes through CLOSE_WAIT.
There are ways to change this (on most platforms, you can reduce the amount
of time a socket spends in CLOSE_WAIT before going to CLOSED), but it may not
be a good idea to use them. The CLOSE_WAIT state helps make sure that all
data is delivered to the right TCP connection and not a different, unrelated
TCP connection by accident.
More information about the Twisted-Python