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; }
}
Hi zahm,
How's this issue? Were you able to figure out what's preventing the reconnection after 50 to 60 connections? Unfortunately, I wasn't able to find something that could help. If you can't still receive a helpful answer from this forum, maybe you'd like to submit a ticket to Renesas Technical Support: https://en-support.renesas.com/dashboard.
JBIf this response, or one provided by another user, answers your question, please verify the answer. Thank you!Renesas Engineering Community Moderatorhttps://community.renesas.com/https://academy.renesas.com/https://en-support.renesas.com/knowledgeBase/
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.
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.
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]);
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); } }
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)); }
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;}