Rick,
Yes, you can open another connection while the old
one is in TIME_WAIT.
You must allocate a new PCB to establish a new
connection (you can't reuse the existing one).
While your station is in TIME_WAIT, the
other station might still be trying to close the connection and may have missed
your ACK, so it is in the LAST_ACK state until it gets an ACK from you, or
its own timer expires. If it has received your ACK then it is already in the
CLOSED state. You can't tell.
If you reopen a connection to the same station
using the same port numbers at both ends, there could be problems since it will
look like the same connection. This is avoided by using a different/random
local port number when you open a new connection. (I haven't looked into how
lwip handles this.)
If you have spare PCBs then this will proceed as
normal, and the old PCB will remain in the TIME_WAIT state until its timer
expires, at which point it is closed and freed by tcp_slowtmr().
If you have no spare PCBs, then tcp_alloc() or
tcp_new() will look for any PCBs in the TIME_WAIT state and immediately close
the oldest one, freeing it so it can be reallocated. If this happens and the
other station had missed your first ACK, then when it retries the FIN it will
get a RST response and this will result in it closing the old connection
anyway.
If you are getting a callback on transition to the
CLOSED state and you are overlapping a new connection with the TIME_WAIT state
of the old one, then your callback handler must pay attention to which
PCB was closed, so you don't think your new connection has closed.
----- Original Message -----
Sent: Thursday, February 14, 2008 11:30
AM
David,
Thanks for the prompt reply, this was
helpful. My slow timer is working just fine and I discovered that if I
wait for 2 minutes the state does eventually change to CLOSED. Is it
valid to conclude that when the state goes to TIME_WAIT that the connection is
properly closed at that point and can be openned again? Or do I have to
wait for the timeout to complete before attempting to start a new
connection? What do you think?
Rick
----- Original Message -----
Sent: Wednesday, February 13, 2008 4:00
PM
Rick Culver wrote:
I am using CALLBACK API and a single TCP
connection. If I close the connection from the remote end everything
is fine the state eventually goes back to CLOSED. However, if I try
to close the connection from my end with tcp_close() the state goes
from 4 to 5 to 6 to 10 and never goes to the CLOSED (0) state. Am I
missing a step in closing the connection or what seems to be the
problem. I appreciate any help you can
provide.
Using symbolic names, that's
ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, then TIME_WAIT.
This means you have sent FIN, received
ACK, received FIN and sent ACK, so the connection is fully closed. The
TIME_WAIT state is there to deal with ACKing retries of the received
FIN if your first ACK reply was lost. It transitions automatically to
CLOSED after a timeout.
If the connection is closed by the other end
first, a different series of states are used: CLOSE_WAIT, LAST_ACK, then
CLOSED. The events are receive FIN, send ACK, close() called locally, send
FIN, receive ACK. The TIME_WAIT state is not used, but the LAST_ACK state
also has a timeout (if the ACK never arrives).
From a quick glance at the source code in lwip
1.2.0, the timeout in the TIME_WAIT and LAST_ACK states is handled by
tcp_slowtmr(), based on the _expression_ 2 * TCP_MSL (two minutes) divided by
TCP_SLOW_INTERVAL.
If your timer implementation has a problem,
e.g. tcp_slowtmr() isn't being called at all, or isn't being called at
the rate specified in TCP_SLOW_INTERVAL, then this would explain a timeout
never occurring, or taking much longer than
expected.
|