SOCKETS

Hi ,

I use RA6m5 with RTOS TCP/IP stack.

I make tests about TCP connection and reconnection .

I configure my socket to accept connection from a host. The host send 50 bytes message when i receive this packet i send to the host 50 bytes. After 6 exchanges the host close the connection. This run in a loop.

Then when FreeRTOS_recv return me -pdFREERTOS_ERRNO_ENOTCONN i create a new socket.  After several reconnections ( 50 - 60) it doesn't work, i receive err -12 on recv or send data and FreeRTOS_accept function always failed.

Then i plug off ip wire and plug in and then the mecanism work.

What is the best way to reconnect a socket for multiple closed connections.

indexLstdSocket always = 0;

bool ReconnectSocket(void)
{
BaseType_t status = pdFALSE;
bool bRes = false;

if(xConnectedSocket[indexLstdSocket] && xConnectedSocket[indexLstdSocket] != FREERTOS_INVALID_SOCKET)
{
  xConnectedSocket[indexLstdSocket]->u.xTCP.ucTCPState = eESTABLISHED;
  FreeRTOS_shutdown(xConnectedSocket[indexLstdSocket],FREERTOS_SHUT_RDWR);
  FreeRTOS_closesocket(xConnectedSocket[indexLstdSocket]);
}

vTaskDelay(100);

xSocket[indexLstdSocket] = NULL;
xConnectedSocket[indexLstdSocket] = NULL;
CreateTcpSocket();


status = FreeRTOS_bind(xSocket[indexLstdSocket], &xBindAddress, sizeof( &xBindAddress ));
if(!status)
{
  memcpy(s_print_buffer,"Binding OK \r\n\0",14);
  PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
}

if(xSocket[indexLstdSocket]->u.xTCP.ucTCPState != eTCP_LISTEN)
{
  status = FreeRTOS_listen(xSocket[indexLstdSocket],2);
  if(!status)
  {
     memcpy(s_print_buffer,"Listen OK \r\n\0",13);
     PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
  }
  else
  {
    memcpy(s_print_buffer,"Listen Failed \r\n\0",17);
    PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
  }
}

memcpy(s_print_buffer,"Attente Connect \r\n\0",19);
PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
xConnectedSocket[indexLstdSocket] = FreeRTOS_accept( xSocket[indexLstdSocket], &xClient, &xSize );

if(xConnectedSocket[indexLstdSocket] != FREERTOS_INVALID_SOCKET && xConnectedSocket[indexLstdSocket] != NULL)
{
  memcpy(s_print_buffer,"Connection Connected\r\n\0",23);
  PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
  bRes = true;
}
else
{
  memcpy(s_print_buffer,"Connection Failed\r\n\0",20);
  PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
  bConnectSocketFailed = true;
}
return bRes;
}

bReuseSocket always true.

/// -----------------------------------------------------------------------------------------------------------------------------
/// @brief CreateTcpSocket Fonction de creation du socket TCP pour la liaison avec le GAC
///
/// @param[in] None
/// @retval None
///
/// -----------------------------------------------------------------------------------------------------------------------------
void CreateTcpSocket(void)
{
static const TickType_t xReceiveTimeOut = 5000; //portMAX_DELAY = infinite

if(!xSocket[indexLstdSocket])
{
  xSocket[indexLstdSocket] = FreeRTOS_socket( FREERTOS_AF_INET,FREERTOS_SOCK_STREAM,FREERTOS_IPPROTO_TCP );
/* Check the socket was created successfully. */
if( xSocket[indexLstdSocket] != FREERTOS_INVALID_SOCKET )
{
  #if( ipconfigUSE_TCP_WIN == 1 )
  WinProperties_t xWinProps;
  memset( &xWinProps, 0, sizeof( xWinProps ) );
  // Fill in the buffer and window sizes that will be used by the socket.
  xWinProps.lTxBufSize = ipconfigTCP_TX_BUFFER_LENGTH;
  xWinProps.lTxWinSize = config_SERVER_TX_WINDOW_SIZE;
  xWinProps.lRxBufSize = ipconfigTCP_RX_BUFFER_LENGTH;
  xWinProps.lRxWinSize = config_SERVER_RX_WINDOW_SIZE;
  #endif
  //Set a time out so accept() will just wait for a connection.
  FreeRTOS_setsockopt( xSocket[indexLstdSocket], 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
  if(bReuseSocket)
    FreeRTOS_setsockopt( xSocket[indexLstdSocket],0,FREERTOS_SO_REUSE_LISTEN_SOCKET,( void * ) &bReuseSocket,sizeof( bReuseSocket ) );
/* The socket was created successfully and can now be used to send data
  using the FreeRTOS_sendto() API function. Sending to a socket that has
  not first been bound will result in the socket being automatically bound
  to a port number. Use FreeRTOS_bind() to bind the socket to a
  specific port number. This example binds the socket to port 9999. The  
  port number is specified in network byte order, so FreeRTOS_htons() is
used. */
#if( ipconfigUSE_TCP_WIN == 1 )
  FreeRTOS_setsockopt( xSocket[indexLstdSocket], 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) );
#endif
  memcpy(s_print_buffer,"Create Socket OK\r\n\0",19);
  PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
  }
}
else
{
  memcpy(s_print_buffer,"Create Socket KO\r\n\0",19);
  PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
  xSocket[indexLstdSocket] = NULL;
}

}

Parents Reply
  • Hi JB,

    Yes i know why the reconnection failed it's because memory allocation failed when i call FREERTOS_recv or FREERTOS_send. After several try the FREERTOS_Accept failed too.
    There is a memory leak somewhere but i can't identify where. 
    I submit a ticket to Renesas Support.

    Best Regards.

Children
  • Hi JB,

    I modify my reconnect() code then when bReuseSocket is true the problem is fixed, i run the code 4 hours with more than 500 reconnections without errors. But when bReuseSocket = false the new code and old has no effect the problem is stil present.

    bool ReconnectSocket(void)
    {
    BaseType_t status = pdFALSE;
    bool bRes = false;


    if(xConnectedSocket[indexLstdSocket] && xConnectedSocket[indexLstdSocket] != FREERTOS_INVALID_SOCKET)
    {
    if(!bReuseSocket)
    {

    if(xConnectedSocket[indexLstdSocket]->u.xTCP.rxStream)
    vPortFreeLarge(xConnectedSocket[indexLstdSocket]->u.xTCP.rxStream);
    xConnectedSocket[indexLstdSocket]->u.xTCP.rxStream = NULL;

    if(xConnectedSocket[indexLstdSocket]->u.xTCP.txStream)
    vPortFreeLarge(xConnectedSocket[indexLstdSocket]->u.xTCP.txStream);
    xConnectedSocket[indexLstdSocket]->u.xTCP.txStream = NULL;

    }
    #if( ipconfigUSE_TCP_WIN == 1 )
    vTCPWindowDestroy(&xConnectedSocket[indexLstdSocket]->u.xTCP.xTCPWindow);
    #endif

    xConnectedSocket[indexLstdSocket]->u.xTCP.ucTCPState = eESTABLISHED;

    FreeRTOS_shutdown(xConnectedSocket[indexLstdSocket],FREERTOS_SHUT_RDWR);
    FreeRTOS_closesocket(xConnectedSocket[indexLstdSocket]);

    }

    vTaskDelay(100);

    if(!bReuseSocket)
    {

    if(xSocket[indexLstdSocket] && xSocket[indexLstdSocket] != FREERTOS_INVALID_SOCKET)
    {

    if(xSocket[indexLstdSocket]->u.xTCP.rxStream)
    vPortFreeLarge(xSocket[indexLstdSocket]->u.xTCP.rxStream);
    xSocket[indexLstdSocket]->u.xTCP.rxStream = NULL;

    if(xSocket[indexLstdSocket]->u.xTCP.txStream)
    vPortFreeLarge(xSocket[indexLstdSocket]->u.xTCP.txStream);
    xSocket[indexLstdSocket]->u.xTCP.txStream = NULL;

    #if( ipconfigUSE_TCP_WIN == 1 )
    vTCPWindowDestroy(&xSocket[indexLstdSocket]->u.xTCP.xTCPWindow);
    #endif


    xSocket[indexLstdSocket]->u.xTCP.ucTCPState = eESTABLISHED;
    FreeRTOS_shutdown(xSocket[indexLstdSocket],FREERTOS_SHUT_RDWR);
    FreeRTOS_closesocket(xSocket[indexLstdSocket]);

    R_ETHER_LinkProcess(g_ether0.p_ctrl);
    R_ETHER_BufferRelease(g_ether0.p_ctrl);
    R_ETHER_Close (g_ether0.p_ctrl);
    R_ETHER_Open (g_ether0.p_ctrl,g_ether0.p_cfg);
    }
    }

    vTaskDelay(100);

    xSocket[indexLstdSocket] = NULL;
    xConnectedSocket[indexLstdSocket] = NULL;
    CreateTcpSocket();
    bRes = Bind();
    return bRes;
    }

    bool Bind(void)
    {
    bool bRes = false;
    BaseType_t status = pdTRUE;
    //Cette fonction est Static dans le driver il a fallut lui oter cet attribut pour compiler.
    ListItem_t * myItem = pxListFindListItemWithValue( &xBoundTCPSocketsList, ( TickType_t ) FreeRTOS_htons( 10001 ) );
    if(myItem)
    uxListRemove(myItem );


    memset( &xBindAddress,0,sizeof(xBindAddress ));
    xBindAddress.sin_addr = FreeRTOS_inet_addr_quick( 10, 13, 22, 210 );
    xBindAddress.sin_port = FreeRTOS_htons( 10001 );
    status = FreeRTOS_bind(xSocket[indexLstdSocket], &xBindAddress, sizeof(xBindAddress ));
    if(!status)
    {
    memcpy(s_print_buffer,"Binding OK \r\n\0",14);
    PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
    }

    if(xSocket[indexLstdSocket]->u.xTCP.ucTCPState != eTCP_LISTEN)
    {
    status = FreeRTOS_listen(xSocket[indexLstdSocket],2);
    if(!status)
    {
    memcpy(s_print_buffer,"Listen OK \r\n\0",13);
    PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
    }
    else
    {
    memcpy(s_print_buffer,"Listen Failed \r\n\0",17);
    PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
    }
    }

    memcpy(s_print_buffer,"Attente Connect \r\n\0",19);
    PRINT_TO_CONSOLE(s_print_buffer,strlen(s_print_buffer));
    xSize = sizeof(xBindAddress );
    xConnectedSocket[indexLstdSocket] = FreeRTOS_accept( xSocket[indexLstdSocket], &xBindAddress, &xSize );
    if(xConnectedSocket[indexLstdSocket] != FREERTOS_INVALID_SOCKET && xConnectedSocket[indexLstdSocket] != NULL)
    {
    memcpy(s_print_buffer,"Connection Connected\r\n\0",23);
    PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
    bRes = true;
    }
    else
    {
    memcpy(s_print_buffer,"Connection Failed\r\n\0",20);
    PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
    memcpy(s_print_buffer,"prvProcessNetworkDownEvent\r\n\0",29);
    PRINT_TO_CONSOLE((void*)s_print_buffer,strlen(s_print_buffer));
    prvProcessNetworkDownEvent();
    vTaskDelay(500);
    bConnectSocketFailed = true;
    }
    return bRes;
    }