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/F28M36P63C2: Error Sockets not blocking?

Part Number: F28M36P63C2


Tool/software: TI-RTOS

I have been trying to debug a problem with the TCP sockets that appears as if they are not blocking.

To pin the problem down I reinstalled TI-RTOS 2.16.1.14 and imported the tcpEcho demo and made minimal modifications to reproduce the problem.

Notice the actual demo program runs in an infinite loop returning 0 bytes consuming the available CPU cycles until data is on the socket.  BSD sockets (which it is using) are supposed to block until there is data on the socket, a timeout occurs, or error (with errno set).  To reproduce the problem I modified the tcpWorker() subroutine as follows:

Void tcpWorker(UArg arg0, UArg arg1)  {
    int clientfd = (int)arg0;
    int bytesRcvd;
    int bytesSent;
    char buffer[TCPPACKETSIZE];
    int notdone = true;

    System_printf("tcpWorker: start clientfd = 0x%x\n", clientfd);

    while (notdone) {
        // should block until TCPPACKETSIZE bytes are received or error.
        bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, MSG_WAITALL);
        System_printf ("received %d bytes. errno = %d.\n", bytesRcvd, errno);
        System_flush ();

        bytesSent = send(clientfd, buffer, bytesRcvd, 0);
        if (bytesSent < 0 || bytesSent != bytesRcvd) {
             System_printf("Error: send failed.\n");
             break;
        }
     }
    System_printf("tcpWorker stop clientfd = 0x%x\n", clientfd);
    System_flush();

     close(clientfd);
}

Notice even when I specified MSG_WAITALL (I tried without as well) that recv() continues to return 0 bytes with no errno set.

I tried reporting the problem before but didn't get any useful responses so I am trying again.

Thanks,

- Gary Brack

  • Hi Gary,

     

    Sorry I dropped off the other thread. I thought I had handed it off before my long weekend. I just ran the TCP Echo example and could not reproduce your issue. I was using a TM4C instead of a Concerto board...need to find one to try it out there.

     

    Here are the steps I did

    1. Build/Run out of box TCP Echo

    2. See target's IP address in CCS console

    3. Run tcpSendReceive.exe from my laptop (>tcpSendReceive.exe 146.252.162.119 1000 0). Let it print out a couple times to see it is working

    4. Run WireShark also to confirm packets are going back and forth.

    5. Ctrl-S the tcpSendReceive.exe

    6. Halt the target and look at ROV->Task->Call Stack to confirm that the tcpWorker is in recv.

    7. Place a breakpoint in tcpWorker after the receive.

    8. Resume the target and confirm the breakpoint is not hit.

    9. Ctrl-Q the tcpSendReceive.exe and confirm the breakpoint is hit on the target.

     

    I repeated the above steps with your code snippet and got the same result. The only change I made was remove the System_flush since that makes the test easier to run.

     

    Todd

  • Todd,

    I am not familiar with the TM4C board so I can't comment about any differences between that and the Concerto, or even if the there are differences between the tcpEcho demos.  

    From the sounds of your test it seems as if you made no modifications to the tcpWorker() subroutine.  Assuming no changes, and the demo code is the same your tcpWorker() routine would have been:

    Void tcpWorker(UArg arg0, UArg arg1)
    {
        int  clientfd = (int)arg0;
        int  bytesRcvd;
        int  bytesSent;
        char buffer[TCPPACKETSIZE];
    
        System_printf("tcpWorker: start clientfd = 0x%x\n", clientfd);
        System_flush();
    
        while ((bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0)) > 0) {
            bytesSent = send(clientfd, buffer, bytesRcvd, 0);
            if (bytesSent < 0 || bytesSent != bytesRcvd) {
                System_printf("Error: send failed.\n");
                break;
            }
        }
        System_printf("tcpWorker stop clientfd = 0x%x\n", clientfd);
    
        close(clientfd);
    }

    It is unclear to me how you inserted a breakpoint after recv() within the while loop expression.  What I observe is the recv() call continually returns 0 causing >0 test to fail and calling receive again until finally a message is received.  That is why in my modified version I moved the recv() inside the while loop and changed it to a while(true) infinite loop.  To confirm returning 0, I added printing recvBytes and errno to demonstrate the return of 0 bytes (which should only happen if there is an error (timeout, socket closed, etc).  

    After producing the error and not believing it I went ahead and stepped through the recv() call (through the TI-RTOS/ndk subroutine calls) and could not find a semaphore on the recv buffer that it would be able to do a semTake() and let the OS block it so that the ndk task could do a semGive() when it would receive data on the socket.  (But the TM4C board could be different)

    One other difference I noticed with your test was that you ran the test client and let it send data first.  I only went so far as to let it do the connect() to cause the tcpWorker() task to be created but never sent any data.  I don't think it matters, I just thought I should mention it.

  • Hi Gary,

    I found a Concerto board. I tried to replicate your setup. I have a tool on my laptop that just connects to port 1000. I have a breakpoint at lines 8, 12, and 18 in the above code. Once I connect, I hit breakpoint 8 as expected, so I continue. I wait for awhile (~40 seconds) and I never hit another breakpoint. Once I disconnect the tool, I hit breakpoint 18 (as expected) on the Concerto board.

    When I look in WireShark, I see the following  (note 146.252.163.100 is the Concerto board)

    No other data was transmitted on the socket. What are you seeing on WireShark? I only get bytesRcvd of zero when the connection is being torn down.

    Todd

  • Todd,

    I am on vacation until 7/31.  I will pick this up when I get back.

    - Gary

  • Sounds good. Thanks for letting me know. Have a great break!

    Todd