This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/PROCESSOR-SDK-OMAPL138: FTP - problems with transfer when change size of SO_RCVBUF and SO_SNDBUF

Part Number: PROCESSOR-SDK-OMAPL138
Other Parts Discussed in Thread: OMAPL138

Tool/software: TI-RTOS

Hello,

I'm using the latest SDK and I have a problem with FTP data transfer.

I changed the size of the send/receive buffer by using:

setsockopt(ioh->data_socket, SOL_SOCKET, SO_SNDBUF, &valSnd, sizeof(valSnd));

setsockopt(ioh->data_socket, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));

When I used default size of the the send/receiver buffer my data transfer suspended!

When I changed the size to 2048, transfer of ONE file is fine, but when I am trying send/receive more then one file my transfer suspended.

The next observation: when I changed buffer size to 1kB data transfer is OK (also for parallel transfer of more than one file), but speed transfer is very very slow!

I noticed that when my program doesn't receive the ACK form the PC it sends the frame again and in CCS CONSOLE I see (00691.900 TcpTimeoutRexmt: Retransmit Timeout), when I have a small buffer, I see the frames being sent again in Wireshark, but when I have a larger buffer I see only a retransmission frames in the CCS Console (I don't see it in Wireshark) and the transfer suspend here.

What can I do to improve my transfer?

I attach an attachment *.cfg2437.app.cfg

  • Hi,

    Are you able to provide the Processor SDK RTOS release version and NDK version info? Is your code based on the NIMU_FtpExample_<board>_<cpu>ExampleProject and ported to L138?

    Is this the befault setting (from .cfg):

    Tcp.transmitBufSize = 16384;
    Tcp.receiveBufSize = 65536;
    Tcp.receiveBufLimit = 65536;

    Regards, Eric

  • Hi Eric,

    Thank you for your answer.

    I am using ti-processor-sdk-rtos-omapl138-lcdk-06.00.00.07-Windows-x86-Install.exe and this product includes ndk_3_60_00_13.

    Yes, my code is based on the NIMU_FtpExample ExampleProject and ported to OMAPL138.

    I didn't create Example Project I used files from ti\pdk_omapl138_1_0_9\packages\ti\transport\ndk\nimu\example\ftpApp\ftpserver

    Is this the befault setting (from .cfg):
    Tcp.transmitBufSize = 16384;
    Tcp.receiveBufSize = 65536;
    Tcp.receiveBufLimit = 65536;

    What is wrong with the above values?

    When I use new values in my code the values set in *.cfg are overwritten, that's right?

    Additionally, when I pull out eth plug, I noticed also retransmit but when I pull the eth plug back in, transmission continues.

    The photo shows behavior when the transmission is suspended.

    Additionally, when I disable cache all works fine also after increasing the size of the buffer but transfer speed is very low...

    Regards, Patryk

  • Any suggestions?

  • Hi,

    In general, you want to make the TCP transmitBufSize and receiveBufSize as large as the app will allow, as the size of these buffers will affect the throughput performance of a TCP connection. TCP buffer sizes (window) is capped at 64K (see TCP_MAXWIN in NDK).

    The settings in *.cfg file are configuring the default values for when any TCP socket is created. Note that the receiveBufLimit size only affects no-copy sockets (that are used with the no-copy APIs, such as recvnc() )

    • Tcp.transmitBufSize = 65536;
    • Tcp.receiveBufSize = 65536;
    • Tcp.receiveBufLimit = 65536;

    This can be overridden after the socket has been created by using the setsockopt() API, as you show in the “C code” section.

    • setsockopt(ioh->data_socket, SOL_SOCKET, SO_SNDBUF, &valSnd, sizeof(valSnd));
    • setsockopt(ioh->data_socket, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));

    I would like to suggest you keeping the cache enabled, and setting TCP TX/RX buffer with 64K and changing the buffer size using C code to get the optimized values.

    Regards, Eric 

  • Hi Eric,

    I add to this thread new observations:

    My program works fine but see my settings:

    int val = 32768;
    int valSnd = 1500; //DON'T CHANGE!!!
    
    setsockopt(ioh->data_socket, SOL_SOCKET, SO_SNDBUF, &valSnd, sizeof(valSnd));
    setsockopt(ioh->data_socket, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));
    
    //...
    //My function to send data:
    numSent = send(connection, ioh->DataBuf, numRead, 0); //ioh->DataBuf has 32kB size

    When I increased SO_SNDBUF my send function return -1 and all the time on the console I see: TcpTimeoutRexmt: Retransmit Timeout. My ftp_server frozen and never becomes alive.

    Regards, Patryk

  • Hi,

    Thanks for the update! Not sure if you still in vacation or already back to office. With a small send buffer of 1500 bytes, what is the throughput? Is it satisfactory?

    Regards, Eric

  • Hi,

    Thank you for answer,

    When my buffer is 1500 bytes I have throughput ~2,5MB/s (but transfer is limited by SD card f_read()).

    But when SO_RCVBUF is 32768 transfer transfer is ~5,5 MB/s (f_write()).

    Regards, Patryk

  • Hi,

    Theoretically, f_read() is faster than f_write() for a MMCSD card. If your f_write() is 5.5MB/s, what is the f_read() speed standalone (without sending out data to network)? And if you just send a buffer containing garbage data repeatedly using NDK, will SO_SNDBUF >  1500 bytes caused TCP transmit time-out? 

    I want to separate the NDK and MMCSD to understand what the issue on NDK alone with SO_SNDBUF.

    Of course, if you are satisfied with the current throughput, we can close this topic.

    Regards, Eric

  • Hi,

    f_read() speed is more then f_write() and without sending out data to network is more then 10 MB/s.

    Yes, always when I have buffer size more then 1500 bytes it caused TCP transmit time-out..

    MMCSD is insignificant in this case.

    Throughput is too low, because I using FTP to transfer large file.

    Regards, Patryk

  • Patryk,

    Thanks! Let me check my colleague in NDK team if they have any suggestions.

    Regards, Eric

  • Patryk,

    Thanks for the patience! Here is the feedback from our NDK team:

    We could send Eric the following thoughts/questions I had while looking this over:

     

    When I increased SO_SNDBUF my send function return -1 and all the time on the console I see: TcpTimeoutRexmt: Retransmit Timeout.

     

    Is the socket blocking or non-blocking?

     

    What is the value of errno when send() returns -1?

     

    when I disable cache all works fine also after increasing the size of the buffer but transfer speed is very low

     

    Well this would indicate a cache coherency problem …!

     

    When my buffer is 1500 bytes I have throughput ~2,5MB/s (but transfer is limited by SD card f_read()).

    But when SO_RCVBUF is 32768 transfer transfer is ~5,5 MB/s (f_write()).

     

    What is the client in this case?  Is it a PC or another embdedded device. If the latter case, what is the TCP RX buffer size configured to be on the client?

     

    The need to configure such a small TX socket buffer size in the NDK indicates that the other side is slow to process the data it receives. But, TCP should handle that by informing the NDK that the window size is 0.

     

    If the socket is non blocking, the TX socket buffer (NDK side) may be full and “stuck” due to the exact situation mentioned above (the client’s RX buffer is full and so it has advertised a size zero window). A blocking socket would just block here, until the underlying TCP layer was able to send some data, at which point the send() request could move forward.

     

    But, if the socket is non-blocking, and the TX socket buffer’s full, awaiting the other side’s window to open, then send() would fail and the error code would be EWOULDBLOCK (or EAGAIN, but probably the former).

     

    If that’s the case then they should make the socket be blocking.

    Regards, Eric