WIZnet Developer Forum

How to disconnect and reconnect again?

Hi Guys,
I have wiz550io module in my boards. I use one of this module as a server and the other is a client. My server board always listen the tcp port for connection. In my project my client board will connect the server and ask for a small data (10 byte). After getting answer client will disconnect the port. After a while (20-30 seconds) client will connect again and ask for a data.
My problem is;
When client module try to connect the server module , connection establihed (without problem) and send a data to server. But in server side no data came. After a timeout (my software timeout) I disconnect and close the port. After a while(20-30 seconds) client try to connect server again. connection established (without problem). client send a data, server get data and send back an other data to client. Client get data also without a problem. After that I disconnect and close the port. After next attemp connection also established but no data came to server.

One connection is done, next connection cant be done and repating like that. When I try to connect to PC (with a generic tcp terminal software) as a server, everything is ok. But when I try one wiznet module to an other there is a problem.
I use wiznet library to connect and disconnect.

I will connect 10 server like this and get data from them. But now I try one server and one client. So I have to disconnet and close the port.

What should be the disconnect and reconnect situtation excatly ? Is there any application note or sample project? If connection status is established I call disconnect funciton before close port function.

Hi, I found the problem. There was a mistake in my code. But anyway what happens If there is a established connection between two module and we call close() function without calling disconnect() .

The disconnect() will do the FIN/ACK dance so that both sides can close sockets gracefully, assuming the connection has been maintained. Otherwise, the disconnect() will perform close() on timeout. Here is the source code from the ioLibrary -

/**
 * @ingroup WIZnet_socket_APIs
 * @brief Try to disconnect a connection socket.
 * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client.
 * @note It is valid only in TCP server or client mode. \n
 *       In block io mode, it does not return until disconnection is completed. \n
 *       In Non-block io mode, it return @ref SOCK_BUSY immediately. \n

 * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
 * @return @b Success :   @ref SOCK_OK \n
 *         @b Fail    :\n @ref SOCKERR_SOCKNUM  - Invalid socket number \n
 *                        @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
 *                        @ref SOCKERR_TIMEOUT  - Timeout occurred \n
 *                        @ref SOCK_BUSY        - Socket is busy.
 */

int8_t disconnect(uint8_t sn)
{
    CHECK_SOCKNUM();
    CHECK_SOCKMODE(Sn_MR_TCP);
    setSn_CR(sn, Sn_CR_DISCON);
    /* wait to process the command... */
    while (getSn_CR(sn));
    sock_is_sending &= ~(1 << sn);
    if (sock_io_mode & (1 << sn)) return SOCK_BUSY;
    while (getSn_SR(sn) != SOCK_CLOSED)
    {
        if (getSn_IR(sn) & Sn_IR_TIMEOUT)
        {
            close(sn);
            return SOCKERR_TIMEOUT;
        }
    }
    return SOCK_OK;
}

Nothing happens if you perform CLOSE, and it can be good, as well as bad. It is bad in the cases when remote device will still think that your device has something to say, and keep its socket open. That socket of remote device of course should be closed with time out, but it may happen if device has limited number of sockets it will get full stack open, and will not be able to accept more connections.

So generally it is a good practice to call DISCON before you call CLOSE in case W5500 socket is in ESTABLISHED state. Though you may not need to wait for DISCON to get socket to the closed state, but just doing DISCON and then after disconnect command finishes doing CLOSE. If remote device will want to say something, it will get RST from the W5500.

Hi, I had a problem about the situation that you just talked about. How can I DISCON in CLOSED or INIT state? Because when internet has problem and disconnect TCP client, but in remote device still keep its socket open so that device cannot connect to that socket. So how do I reclose socket from client side without waiting for timeout?

I think you have to read the value of Sn_SR and the status of W5500 is sending FIN packet or was sent FIN packet.
I think you can also know the TCP Server status.
Generally I’m using the wireshark(packet capture program) when used for test and you can also see the packet using program.
If it is possible, please check the status of W5500 or TCP Server and let me know.

Both operations are invalid from the internal W5500 network stack standpoint. If socket is in closed or initialized state, result of DISCON command is neither defined nor guaranteed. Look here at page 29, W5500 is the same. There’s no place for DISCON command other than in ESTABLISHED or SOCK_CLOSE_WAIT socket states.

The remote device must have timeout, and it will close its hung socket after some time (driven by this timeout or by probing).

You must use different local port number within W5500 for TCP communication creating new connection and continuing communication through this new connection.

If remote server has reset the current connection, or W5500, after prolonged interval of connection interruptoin will reset current connection, there’s no way to resume it, and you must make new one.

The flow is the folllowing:

  1. every time you make new connection, you use new local port number.
  2. if you need to close the current connection to the server, you perform DISCON, wait until CR clears, and then immediately perform CLOSE and proceed to point (1) opening new connection with new port number.

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.