How to end a TCP client task?

Hi all, I’m looking for an idea how to stop / end / kill a task which stucks in a possibly long or endlos lasting wait situation. At my embedded system FreeRTOS-TCP creates several TCP client tasks by a listener task. The embedded system acts as a server, which is connected to a PC via Ethernet/TCP. When now the PC client fails or the connection is broken otherwise, the client-task on the embedded server possibly still runs and is stuck in a send or receive routine with big timeouts, or waits otherwise for a situation that will never happen. So how could such ghost-tasks be ended or killed when after a failing situation the PC program us restarted. The system works of course also without ending these, now useless, tasks, but the number of TCP tasks is normally limited and will soon reach this limit. I hope I could explain my problem and am glad, if someone can help with ideas. Greetings

How to end a TCP client task?

HI Johannes, First: I would let these tasks take control of the situation, let the task decide when a connection is considered dead. You can control the maximum blocking time per API. That is documented on ~~~

define FREERTOSSORCVTIMEO ( 0 ) /* Used to set the receive time out. */

define FREERTOSSOSNDTIMEO ( 1 ) /* Used to set the send time out. */

~~~ FreeRTOS+TCP has mechanisms to detect an orphaned connection, which happens when the peer has left without a graceful closure. ~~~ /* Include support for TCP hang protection. All sockets in a connecting or disconnecting stage will timeout after a period of non-activity. */

define ipconfigTCPHANGPROTECTION ( 1 )

define ipconfigTCPHANGPROTECTION_TIME ( 30 )

/* Include support for TCP keep-alive messages. */

define ipconfigTCPKEEPALIVE ( 1 )

define ipconfigTCPKEEPALIVE_INTERVAL ( 20 ) /* in seconds */

~~~ If possible, it is even better to implement this protection at a higher level: send a are-you-alive (AYA) message at regular intervals to check if the connection is still OK. These messages only have to be sent as long as there is no other traffic. I think there is no need to detect and kill ghost tasks: make them responsible for their connections and let them kill them selves when done. Security: I sometimes do have a (software) watchdog that must be touched regularly by all tasks, e.g. every minute. But when that watchdog goes off, it’s like an exception: it will cause a reset of the CPU, and the event will be reported. If you have plenty of resources, it’s fine to handle one socket per task. But if you have little RAM, you can use one of the many techniques to handle a who set of socket within one task. Think of: ~~~ /* Use FreeRTOS_select() */


/* Use call-backs */

if ipconfigUSE_CALLBACKS == 1

#define FREERTOS_SO_TCP_CONN_HANDLER  (  6 )  /* Install a callback for (dis) connection events */
#define FREERTOS_SO_TCP_RECV_HANDLER  (  7 )  /* Install a callback for receiving TCP data */
#define FREERTOS_SO_TCP_SENT_HANDLER  (  8 )  /* Install a callback for sending TCP data */
#define FREERTOS_SO_UDP_RECV_HANDLER  (  9 )  /* Install a callback for receiving UDP data */
#define FREERTOS_SO_UDP_SENT_HANDLER  ( 10 )  /* Install a callback for sending UDP data */

endif /* ipconfigUSE_CALLBACKS */

/* Connect each socket with a semaphore. */


#define FREERTOS_SO_SET_SEMAPHORE    ( 3 )        /* Used to set a user's semaphore */


~~~ The above is all documented on and often discussed on this forum.

How to end a TCP client task?

Thank you very much Hein, for your detailed advice. To remove any client-ghost-tasks, I think I will start with changing the timeouts and enable the keep-alive mechanism.