Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

FreeRTOS_recv returns pdFREERTOS_ERRNO_ENOTCONN but also all the data

Posted by joehinkle on January 3, 2019

How do you delete a post?


FreeRTOS_recv returns pdFREERTOS_ERRNO_ENOTCONN but also all the data

Posted by heinbali01 on January 5, 2019

Just in case some readers are curious about the title of this post, here is an explanation:

It is not uncommon to shut down a TCP connection immediately after sending some data.

When your application runs on a laptop, it is usually safe to do the following:

send( socket, buffer, length, 0 );
shutdown( socket, SHUT_RDWR );
close( socket );

When an application closes a socket, the OS will take care of the socket and make sure that the data will be delivered before the socket is destroyed.

Under FreeRTOS+TCP, when you close a socket (FreeRTOS_closesocket()), the socket will be destroyed immediately and the TCP connection will be aborted in a non-gracious way.

You will have to wait for the connection to get closed (-pdFREERTOS_ERRNO_ENOTCONN).

~~~ FreeRTOSsend( xSocket, pcBuffer, uxLength, 0 ); FreeRTOSshutdown( xSocket, FREERTOSSHUTRDWR ); for( ;; ) { BaseType_t xResult;

    xResult = FreeRTOS_recv( xSocket, pcBuffer, sizeof( pcBuffer ), 0 );
    /* Testing for -pdFREERTOS_ERRNO_EAGAIN is actually not necessary
    because FreeRTOS_recv() will never return that pseudo error. */
    if( ( xResult < 0 ) && ( xResult != -pdFREERTOS_ERRNO_EAGAIN ) )
    {
        break;
    }
}
FreeRTOS_closesocket( xSocket );

~~~

Calling shutdown() results in sending the FIN flag. But as long as the socket has data queued to be sent, the FIN flag will not be set. Only the TCP packet carrying the last bytes will have FIN set.

This mechanism can be seen when using the FTP server: files with an arbitrary length are being sent. The connection gets closed immediately and gracefully after the last byte.

At the receiving end, it may happen that the connection is closed while the socket still holds received data.

FreeRTOS_recv() will do 5 things:

  • If the socket is invalid, return -pdFREERTOS_ERRNO_EINVAL
  • If the RX stream is not empty, return the number of bytes read
  • If the connection is closed, return -pdFREERTOS_ERRNO_ENOTCONN
  • If the socket has a memory problem, -pdFREERTOS_ERRNO_ENOMEM
  • Or else, if the receive time-out is non-zero: wait for data in a blocking way. Return either 0 or the number of bytes

Finally, one thing about send() / shutdown(): when calling send(), the IP-task will be triggered to start sending the data immediately. It may happen that the packet carrying the last bytes does not have the FIN flag set.

That is not a real problem, it is just less efficient.

When you know that send() is called for the last time, you can set a flag in the socket:

~~~ BaseType_t xTrueValue = 1;

FreeRTOS_setsockopt( xSocket,
                     0,
                     FREERTOS_SO_CLOSE_AFTER_SEND,
                     ( void * ) &xTrueValue,
                     sizeof( xTrueValue ) );
FreeRTOS_send( xSocket, pcBuffer, uxLength, 0 );
/* shutdown() will be done automatically.
Just wait for the connection to close as described above. */

~~~

This is a small optimisation found in FreeRTOS+TCP only.


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS v10.2.0 is available for immediate download. MIT licensed, and including RISC-V and ARMv8-M (Cortex-M33) demos.

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Cadence Tensilica Cortes

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Mediatek

Renesas

RISC-V

SiFIve RISC-V

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner