MODBUS TCP not reconnecting

Hello people,
I have been working on this modbus tcp slave project using freertos and freemodbus library. While it works fine at first, once i disconnect the master software, the tcp connection times out. How can i make it persistent such that i can connect to the slave at anytime and poll fresh data as well.

Hi Torpedod,

From your description, it is difficult to diagnose the reason why the TCP connection times out. More information from you would be helpful. Like what is your TCP/IP stack? The log when TCP connection times out. The code you disconnect and reconnect to the master, etc.

Most FreeRTOS+TCP API’s return:

  • A negative value (-errno) when someting goes wrong
  • Zero when things went OK
  • A positive value like “number of bytes sent/read”

Hopefully your master software sends a proper FIN as soon as it wants to stop. Check the return values of FreeRTOS_recv() and FreeRTOS_send() because they may return an error.

Note that the following errors are not fatal: pdFREERTOS_ERRNO_EAGAIN and pdFREERTOS_ERRNO_EINTR.

If you want you can post the source code that calls FreeRTOS+TCP APIs, and I will look at it.

Here is a simple function that tells you if a socket is still connected:

    /* Returns pdTRUE if TCP socket is connected. */
    BaseType_t FreeRTOS_issocketconnected( ConstSocket_t xSocket );

Normally you do not need it.

If you do not receive FIN packets, because the server does not disconnect gracefully, you can put a timer on your socket: when no data is received within N seconds, call FreeRTOS_closesocket() and continue with a new socket.

And if you want to close gracefully:

    /* Start closing the connection: */
    FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );
    for( ;; )
        BaseType_t xRc = FreeRTOS_recv( xSocket,
                                        sizeof pcBuffer,
                                        0 );
        if( xRc > 0 )
            /* Very important: handle the last bytes received. */
        else if( xRc < 0 )
            if( ( xRc != -pdFREERTOS_ERRNO_EAGAIN ) &&
                ( xRc != -pdFREERTOS_ERRNO_EINTR ) )
                printf("The shutdown is ACK'd by the peer (errno %d)\n", -xRc );
    /* Close ( free ) the socket to free the resources. */
    FreeRTOS_closesocket( xSocket );

One more thing to look at are these config options: ipconfigTCP_HANG_PROTECTION,
They may also help to prevent “hanging” sockets.