Hi,
I am working on a product which uses the Telnet server code supplied with RTCS.
In the product the server needs to be started and stopped on demand.
During testing it was noticed that the server creates 2 sockets when started, but when the server is shut down only one socket is closed.
I have looked through the code and it seems that in the SOCK_STREAM_accept function a new socket is created, then the task blocks waiting for a connection.
When the server is shut down, the task exit handler is called, which frees the first socket, but the second socket is left.
This process is repeated each time the server is started or stopped.
Is there any work-around you can suggest for this?
Thanks
Chris
Solved! Go to Solution.
Ok, I've found a solution - I have modified tcp_clos.c - I've changed TCP_Close_TCB, adding the following to the end of that function:
/*
* Close any sockets opened by accept
*/
prev_req = NULL;
req = tcp_cfg->OPENS;
while( req != NULL )
{
if( ( req->TCB_PTR == tcb ) && ( ( ( SOCKET_STRUCT_PTR )req->SOCKET )->TCB_PTR == NULL ) ) {
void * toBeFreed = req;
SOCK_Free_sock_struct( ( SOCKET_STRUCT_PTR )req->SOCKET );
// Just in case any thread is blocked waiting for this, send req complete.
RTCSCMD_complete( req, RTCSERR_TCP_CONN_RLSD );
// Remove the request from the open requests list
if( prev_req != NULL ) {
prev_req->NEXT = req->NEXT;
}
else {
tcp_cfg->OPENS = req->NEXT;
}
// Move on to the next request
req = req->NEXT;
// Free the old request.
_mem_free( toBeFreed );
}
else {
prev_req = req;
req = req->NEXT;
}
}
This looks for any Open Requests with the same TCB pointer in the request (the TCB of the listening socket), and where the socket has a NULL TCB pointer, and frees the socket.
This does not free any sockets that were spawned by the listening socket that have connected (the socket TCB wouldn't be NULL in that case).
I came across this problem also a while back. I had a similar solution, but I think I like yours better. I didnt do this: RTCSCMD_complete( req, RTCSERR_TCP_CONN_RLSD ); I'm going to try it out. Thanks!
Ok, I've found a solution - I have modified tcp_clos.c - I've changed TCP_Close_TCB, adding the following to the end of that function:
/*
* Close any sockets opened by accept
*/
prev_req = NULL;
req = tcp_cfg->OPENS;
while( req != NULL )
{
if( ( req->TCB_PTR == tcb ) && ( ( ( SOCKET_STRUCT_PTR )req->SOCKET )->TCB_PTR == NULL ) ) {
void * toBeFreed = req;
SOCK_Free_sock_struct( ( SOCKET_STRUCT_PTR )req->SOCKET );
// Just in case any thread is blocked waiting for this, send req complete.
RTCSCMD_complete( req, RTCSERR_TCP_CONN_RLSD );
// Remove the request from the open requests list
if( prev_req != NULL ) {
prev_req->NEXT = req->NEXT;
}
else {
tcp_cfg->OPENS = req->NEXT;
}
// Move on to the next request
req = req->NEXT;
// Free the old request.
_mem_free( toBeFreed );
}
else {
prev_req = req;
req = req->NEXT;
}
}
This looks for any Open Requests with the same TCB pointer in the request (the TCB of the listening socket), and where the socket has a NULL TCB pointer, and frees the socket.
This does not free any sockets that were spawned by the listening socket that have connected (the socket TCB wouldn't be NULL in that case).