What does Sn_SR "SOCK_CLOSING" value (0x1A) mean?

I understand the other “temporary status” values explained on page 51 of the datasheet, but not SOCK_CLOSING. What phase of the socket close process described at The TCP/IP Guide - TCP Connection Termination does this correspond to, if any?

If it doesn’t map to this process, what does it mean and what needs to happen before the socket goes to SOCK_CLOSED?

This status can occur after the close command 0x10 until the socket gets its final state 0x00 closed. (last step in your process)
In every case you should repeat the status request if you receive one of the temporary statuscodes until you receive a clear final state.
If you do new commands before (e.g. disconnect and close without waiting to the end of the disconnect process) it may work but checking the connection with whireshark will show that there are problems.

I do not think so. 0x1A happens after DISCON command. CLOSE will immediately reset the socket and change its status to 0x00.

For the benefit of future readers, I would expect the following sequence of values in a W5x00 Sn_SR after sending a DISCON command to a socket that is in the CLOSE_WAIT state (i.e., that has been half-closed by the remote peer):

  1. CLOSE_WAIT (connection half-closed by remote peer indicating it’s done with the socket)
  2. LAST_ACK (W5x00 has sent ACK/FIN to remote peer indicating it’s done with the socket too and waits for ACK from peer)
  3. CLOSED (both ends agree socket is closed)

If the W5x00 is disconnecting an ESTABLISHED socket, on the other hand, I would expect this sequence of Sn_SR values:

  1. ESTABLISHED
  2. FIN_WAIT (FIN sent to peer; waiting for FIN/ACK response from peer)
  3. TIME_WAIT (waiting for delayed packets from peer, if any, to arrive)
  4. CLOSED (both ends agree socket is closed)

I don’t include the “CLOSING” status in this sequence because I’m not sure where it goes. But I have a suspicion.

Most sources refer to FIN-WAIT-1 and FIN-WAIT-2 to distinguish between the time spent waiting for an ACK to the initial FIN and the time spent waiting for the (possibly later) arrival of a FIN from the other side. This looks like:

  1. ESTABLISHED
  2. FIN_WAIT_1 (FIN sent to peer; waiting for ACK response from peer)
  3. FIN_WAIT_2 (ACK received from peer, waiting for FIN from peer)
  4. TIME_WAIT (waiting for delayed packets from peer, if any, to arrive)
  5. CLOSED (both ends agree socket is closed)

But the W5x00 doesn’t identify FIN_WAIT_1 & FIN_WAIT_2 states, only FIN_WAIT. This leads me to suspect that the “CLOSING” state is really FIN_WAIT_2, which would mean our Sn_SR would go through this sequence of values when a socket is disconnected:

  1. ESTABLISHED
  2. FIN_WAIT (FIN sent to peer; waiting for ACK response from peer)
  3. CLOSING (ACK received from peer, waiting for FIN from peer)
  4. TIME_WAIT (waiting for delayed packets from peer, if any, to arrive)
  5. CLOSED (both ends agree socket is closed)

I was hoping someone from Wiznet could confirm this so I didn’t have to do the experiment to find out if I’m right.

Practically, while answer to the question would be interesting, not sure how it is useful. Application running on W5x00 in TCP mode socket should certainly care about three major states: 0x17 (ESTABLISHED), range of 0x18-0x1D and 0x00 (CLOSED) after establishing connection:

  • if state is ESTABLISHED, then remote device may still has something to say;
  • if state is not ESTABLISHED and not CLOSED (somewhere between 0x18 and 0x1D inclusive), then remote host finished with its communication, and, if W5x00 has nothing more to say, it should perform DISCON and then CLOSE;
  • if state is CLOSED, do nothing as socket is already closed, or perform explicit CLOSE just in case.

All intermediate states of 0x18-0x1D are just “for your information” on what is going on, and for troubleshooting purposes.

DISCON and CLOSE pair may be treated differently given the connection type: for server mode it is wise to perform DISCON and then immediately CLOSE, for client programmer may choose to wait after issuing DISCON to ensure server has confirmed closure of the connection and freed its sockets.

If, for some reason, process will get out of order (e.g. application re-sends FIN when it was already sent before), then the worst case it will get RST back. The main point of the connection termination is to ensure no network device is having socket hung, and thus resources consumed for more time than really needed.

All valid comments. I’m improving an existing Arduino library for W5x00 chips that does some things with sockets that I don’t think it should. As I fix these things, I want to make sure I completely understand what I’m doing. I sleep better when I understand everything (including what the CLOSING state means).

1 Like

I ran tests today and saw the following:

  1. When the peer sends a FIN first, I see Sn_SR change to 0x1D (SOCK_LAST_ACK) before changing to 0x00 (SOCK_CLOSE). I see no intermediate values, though this could be a sampling rate problem.

  2. When the W5x00 sends a FIN first, I see Sn_SR change to 0x18 (SOCK_FIN_WAIT) before changing to 0x1B (SOCK_TIME_WAIT) then 0x00 (SOCK_CLOSE). Sn_IR changes to 0x02 (DISCON) at about the same time. Despite running these tests many times, I never managed to capture Sn_SR with a value of 0x1A. Maybe if I run it from outside my LAN the delay will be long enough to capture it.

These TCP-relevant states of Sn_SR look to be closely related to the general description of how TCP works, for which Wikipedia and Google are useful. The correspondence isn’t quite perfect - e.g. FIN_WAIT_1 and FIN_WAIT_2 aren’t distinguished.

According to the TCP state machine transition diagram at

[Transmission Control Protocol - Wikipedia]

the CLOSING state indicates you’ve sent your FIN and then received a FIN from the other side before your FIN is ACKed. To get into such a state both sides would have to try to active-close at the same time (modulo network delay), and most of the time one would proceed quite quickly into CLOSE_WAIT - because you’d receive the ACK of your FIN soon after. So it seems reasonable you haven’t been able to see it happen.

You might be able to see it by talking through a firewall configured to drop the w5x00’s outgoing FINs.

Great information. Thanks!