I haven’t tried your implementation of a telnet server, but I tested my own server, just to see if there is a memory leak in the library.
If you like, here is a simple implementation of telnet: telnet.c/telnet.h.
This solution does not create any task, it wants to be called by the application.
Here is an example of how to use the telnet module:
#include "telnet.h"
#if ( ipconfigSOCKET_HAS_USER_SEMAPHORE == 0 )
#error Please define ipconfigSOCKET_HAS_USER_SEMAPHORE as '1'
#endif
static Telnet_t xTelnet;
static SemaphoreHandle_t xServerSemaphore;
void my_application( void *pvParameter )
{
char pcBuffer[ 128 ];
xServerSemaphore = xSemaphoreCreateBinary();
configASSERT( xServerSemaphore != NULL );
xTelnetCreate( &xTelnet, TELNET_PORT_NUMBER );
if( xTelnet.xParentSocket != 0 )
{
FreeRTOS_setsockopt( xTelnet.xParentSocket,
0,
FREERTOS_SO_SET_SEMAPHORE,
( void * ) &xServerSemaphore,
sizeof( xServerSemaphore ) );
}
for( ;; )
{
/* Go asleep for at most 200 msec, the Telnet socket might give
* to the semaphore and wake-up this task.
*/
xSemaphoreTake( xServerSemaphore, pdMS_TO_TICKS( 200U ) );
if( xTelnet.xParentSocket != NULL )
{
struct freertos_sockaddr fromAddr;
BaseType_t xCount;
xCount = xTelnetRecv( &xTelnet,
&fromAddr,
pcBuffer,
sizeof( pcBuffer ) - 1 );
if( xCount > 0 )
{
pcBuffer[ xCount ] = 0;
/* Just bounce back the string. */
xTelnetSend( &xTelnet, &fromAddr, pcBuffer, xCount );
}
}
}
}
Some general remarks, after reading your sample code:
Make sure that after calling closesocket()
, the socket is not referred to any more. It is a good habit to clear the pointer:
FreeRTOS_closesocket( pCtrl->socketClient );
pCtrl->socketClient = NULL;
This might avoid an ugly crash.
Quite recently I wrote about the use of shutdown, when to use it and how. See my long post in this forum.
Normally, a TCP server will not shut down a connection. It is the client who initiates a graceful shutdown. The client is e.g. a telnet client or a browser.
Shutdown is applied to a connected socket, and after calling shutdown()
, the socket must continue to exist because shutting down a connection takes time. On a LAN it will take a few milliseconds, but on the Internet it make take up to a few seconds.
Normally, the listening socket is created at boot time, and it continues to exist until the device goes down.
The client sockets obtained with accept() have a temporary life. use them until recv()
or send()
returns an error.