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.

about ndk tcp send

I'm writting some test code on  ndk_2_20_03_24. the CPU is C6748.

code on devices:

char sbuf[8*1024] = {0};
//char sbuf[32*1024] = {0};
Void task0(Arg id_arg)

 int maxfd = 0;
 fd_set readsocks;
 SOCKET s,ds;
 int nSendBuf, i;
 int sendlen = 0;
 struct sockaddr_in remote, local;
 int remotelen = sizeof(struct sockaddr_in);
 int locallen = sizeof(struct sockaddr_in);
 struct timeval timeout;
 timeout.tv_sec = 0;
 timeout.tv_usec = 2000; //2000 u
 memset(sbuf, 0, sizeof(sbuf));
 fdOpenSession( (HANDLE)TaskSelf() );
 
 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 local.sin_family = AF_INET;
 local.sin_port = htons(3277);
 local.sin_addr.s_addr = inet_addr("192.168.1.12");
 
 remote.sin_family = AF_INET;
 bind(s, (PSA)&local, locallen);
 listen(s, 5);
 ds = accept(s, (PSA)&remote, &remotelen);

 nSendBuf = 32*1024;
 setsockopt(ds, SOL_SOCKET, SO_SNDBUF, (void *)&nSendBuf, sizeof(int));
 
 //nodelay = 1;
 //setsockopt(ds, IPPROTO_TCP, TCP_NODELAY, (void *)&nodelay, sizeof(int));
   
    i = 0;
   
 if(ds != INVALID_SOCKET)
 {
  while(1)
  {
   FD_ZERO(&readsocks);
   maxfd = (int)ds;
   FD_SET(ds, &readsocks);
   maxfd++;
   if(fdSelect(maxfd, NULL, &readsocks, NULL, &timeout)>0)
   {   
    if(FD_ISSET(ds, &readsocks))
    {
     i++;
     *(int *)sbuf = i;
     sendlen = send(ds, sbuf, sizeof(sbuf), 0);
     if(sendlen <= 0)
     {
      break;
     }
    }
   }
  }
 fdClose(ds);
 }
 fdClose(s);
 fdCloseSession( (HANDLE)TaskSelf() );
 TSK_exit();
}

code on pc:

#include "stdafx.h"
#include "windows.h"
#include "winsock2.h"
#include <stdio.h>

#pragma comment(lib, "ws2_32.lib")

char rbuf[8192] = {0};
int _tmain(int argc, _TCHAR* argv[])
{
 SOCKET s;
 unsigned short nVer = MAKEWORD(2,2);
 WSAData wsa;
 sockaddr_in remote;
 DWORD prevtick, curtick;
 if(WSAStartup(nVer, &wsa) == 0)
 {
  int reclen = 0, remainsize = 0,totallen = 0, statslen = 0;
  int curM = 0;
  s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  remote.sin_family = AF_INET;
  remote.sin_port = htons(3277);
  remote.sin_addr.s_addr = inet_addr("192.168.1.12");
  FILE * fp = fopen("G:\\test.bin", "wb");
  if(fp)
  {
   if(connect(s,(SOCKADDR *)&remote, sizeof(SOCKADDR))!=SOCKET_ERROR)
   {
    prevtick = GetTickCount();
    while((reclen = recv(s, rbuf, sizeof(rbuf), 0))>0)
    {
     //fwrite(rbuf, 1, reclen, fp);
     statslen += reclen;
     totallen += reclen;
     if(statslen >= 16*1024*1024)
     {
      curtick = GetTickCount();
      printf("recv rate %f mb/s\n", ((float)statslen/(1024.0*1024.0))/(float)(curtick-prevtick)*1000.0);
      statslen = 0;
      prevtick = curtick;
     }
     if(totallen >= 256 *1024 *1024)
     {
      break;
     }
    }
    Sleep(2000);
   }
   fclose(fp);
  }
  closesocket(s);

  WSACleanup();
  return 0;
 }
}

if the sbuf is set to 32*1024 bytes size, the comunication has no problem.
but when I set the sbuf to 8*1024 bytes size, the comunication always stalled after transmit some data.

if anyone can help me?

 

  • Hi Jianguo Yu,

    Which version of BIOS are you using?  DSP/BIOS 5.x?  Or SYS/BIOS 6.x?

    In the failure case, do you know if the send() function is returning a value <= 0?  In other words, is the program ever reaching this point:

       sendlen = send(ds, sbuf, sizeof(sbuf), 0);
         if(sendlen <= 0)
         {
          break;  // <-- does this ever happen?
         }

    You may want to put a break point here to see what send() is returning if this if condition is ever true.  Or, maybe change that code to be something like:

       sendlen = send(ds, sbuf, sizeof(sbuf), 0);
         if(sendlen <= 0)
         {

          printf ("send() call failed: sendlen = %d, error number = 0x%x\n", sendlen, fdError());
          break;
         }

    the value of fdError() should be one of the following:

    ENOTSOCK The file descriptor does not reference a socket.
    EINVAL The input is invalid.
    ENOBUFS Memory allocation failure while attempting to send data.
    ESHUTDOWN The socket has been shut down for writes.
    EMSGSIZE The size of the data being sent exceeds the MTU of the
    interface or the Maximum Transmit buffer size configured
    using SO_SNDBUF option, whichever is the smaller value
    of the two.
    ENXIO No egress interface specified for this socket to send out
    data. Use SO_IFDEVICE socket option and specify an
    interface before retrying to send out data using this socket.

     

    One other thing I noticed, you are still setting the send buffer size to 32K, even though the actual size of 'sbuf' is now 8K.  Could you also try changing the value of nSendBuf:

    nSendBuf = 8 *1024;

    Steve

  • Hi Steve,

    I'm using bios_5_41_07_24

    sendlen = send(ds, sbuf, sizeof(sbuf), 0);
         if(sendlen <= 0)
         {
          break;  // <-- this never happen.
         }

    the program stalled at fdSelect

    when I used ethereal to analyse the TCP communication, I found that after a few second transmit, a TCP segment lost and no TCP retransmission for the lost segment.

    the device transmit the next segments by following. then after a few second, The communication stalled.

  • Jianguo Yu,

    The fdSelect() function never returns?  It should timeout after 2us based on the values of the timeout struct in your code.

     

    Can you try updating your code to the following changes in bold type?  Does it print any useful info for the failure case?  What about for the working case?

    int status = 0;

    ....

      if((status = fdSelect(maxfd, NULL, &readsocks, NULL, &timeout))>0)
       {  
        printf("fdSelect returned %d\n", status);
        if(FD_ISSET(ds, &readsocks))
        {
         i++;
         *(int *)sbuf = i;
         sendlen = send(ds, sbuf, sizeof(sbuf), 0);
         if(sendlen <= 0)
         {
          break;
         }
        }
       }
       else
       {
           printf("ERROR: fdSelect returned %d
    , error number = 0x%x\n", status, fdError());
       }
      }
     fdClose(ds);
     }

     

     

  •  

    Hi Steven,

    There is no problem after I update my code as you metioned. but the recv rate is too slow.(caused by printf("fdSelect returned %d\n", status);)

    I try to use TSK_sleep(10) in my code, the communication is no problem but the recv rate is too slow.

    when I tried TSK_sleep(1) in the location, the seem problem happended

    int status = 0;

    ....

    if((status = fdSelect(maxfd, NULL, &readsocks, NULL, &timeout))>0)
    {    
      if(FD_ISSET(ds, &readsocks))
      {
        i++;
        *(int *)sbuf = i;
        sendlen = send(ds, sbuf, sizeof(sbuf), 0);
        if(sendlen <= 0)
        {
          break;// <-- I toggle a break point here, but never hit
        }
        TSK_sleep(10);// <-- TSK_sleep(1)
      }
    }else
    {
      printf("ERROR: fdSelect returned %d, error number = 0x%x\n", status, fdError());// <-- I toggle a break point here, but never hit
    }

  • Jianguo Yu,

    Yes, my apologies, printf() is very slow.  You should use the BIOS function LOG_printf(&trace,...) instead.  It is much more efficient.

     

    So are you saying that the program has started to work (fdSelect() no longer hangs) after adding the print statements?

    If you are still seeing this hang, can you please zip up your entire project directory, including a pre-built executable, so that I can try to reproduce the problem you are facing here?

    Thanks,

    Steve

  • Hi Steven,

    thanks for your detailed reply.

    I've resolved the problem.

    when I checked the settings of my project last night, I found that the PRD Object was not defined(for function llTimerTick).

    after I added the PRD for llTimerTick to .tcf, The device worked properly.

    thanks again.

    Jianguo.

  • Hello Steven,

    I get the fdError() pointing to EHOSTDOWN when i do a sendto() from my application.

    I get this error not for the First packet sent, but after running the application for some time now. The sendto() is called every 1ms and the error occurs randomly after 5 minutes or 10 minutes... nothing fixed on this.

    Does it mean that the machine to which im sending the data goes down after some time. But at the same time, im also continously PINGing the machine, and the PING is always successful to that machine.

    Is there some way that i can debug this issue regarding the EHOSTDOWN error. Pls help.

    Thanks..

    Santosh

  • Santosh,

    Can you use WireShark to confirm what is going on on the network?

    Todd