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.

TCP Client non blocking or connect timeout

Other Parts Discussed in Thread: TM4C129ENCPDT

Hello everyone!


I am working with TM4C129ENCPDT, TI-RTOs Version 2.14.4.31, NDK Version 2.24.03.35 TI v5.2.6 Compiler. I have implemented a TCP client that connects to a remote server. When the server is not available, the blocking connect() blocks my task eventhough the server is available sometime after the connect() was called. Of course, if the server is available when I call the connect(), evertything works just fine.
Here is my code for the client:

memset(&localAddr, 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = inet_addr(hostaddress);
localAddr.sin_port = htons(hostport);

// Creates socket for the client
socketClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (socketClient == -1) {
 return;
}

// Socket timeouts configuration
socketTimeout.tv_sec = 3;
socketTimeout.tv_usec = 0;
setsockopt(socketClient, SOL_SOCKET, SO_RCVTIMEO, &socketTimeout, sizeof(socketTimeout));
setsockopt(socketClient, SOL_SOCKET, SO_SNDTIMEO, &socketTimeout, sizeof(socketTimeout));

// Connection to the server
if (connect(socketClient, (struct sockaddr *) &localAddr, sizeof(localAddr)) > -1) {
    // Do work
}
close(socketClient);


I tried with (before calling connect()):

int sockopt = 0;
setsockopt(socketClient, SOL_SOCKET, SO_BLOCKING, (char*) &sockopt, sizeof(int));

in this case, I always get connect() = -1, with or without server availability.
How can I make the client non blocking or insert a timeout for the connection (since these send/receive timeouts are not working)?

Thanks in advance for your help!!
Greetings,

Sara

  • Hi Sara,


    Are you positive that a timeout is the issue?  Have you checked why connect is returning -1?

    You can do this by modifying your above code:

    if (connect(socketClient, (struct sockaddr *) &localAddr, sizeof(localAddr)) > -1) {
        // Do work
    }
    else {
        DbgPrintf(DBG_INFO, "connect failed: error = %d\n", errno); // or fdError() if you're using legacy sockets layer
    }

    The error code printed out can be found in the file ti/ndk/inc/serrno.h

    Steve

  • Hi Steve,

    when I have blocking socket, the connect() never returns; and when I have non blocking socket it always returns error=36=EINPROGRESS (operation in progress), whether the server runs or not.

    Just note that, for the test environment I can control the server, so I start and stop it whenever I want. In the application I have to send sometimes data to the server. If the server is not available and the data is lost, there is no problem (I dont need to queue it or whaterver); but when the server is available the client has to be able to send the current data.

    Thanks for your help!!!

    Sara

  • Sara Fernandez said:
    when I have blocking socket, the connect() never returns

    Can you take a Wireshark capture of this scenario?  Are you seeing the TCP SYN packets being sent out to the server?

    Steve

  • Hi Steve,

    yes, I checked with Wireshark. The TCP SYN is sent just once (there are no retransmissions) and it is never answered since the server is not available.  Here two screenshots (192.168.11.121 is my TI-RTOS device and 45 my server): the first one when the server is available and the second without server.

    1) Connection successful

    2) Server not available: connect() blocks forever

      

    If I could set a timeout for the connect() that it stops blocking when there are no answer, it will solve my problem. The thing is, I dont know how.

    Thanks again!!

    Sara

  • Sara,

    I think the setting you need to configure is in your application *.cfg file.  If you open it in XGCONF, it's under the NDK's Ip module.  The setting is called "Connection timeout".  Please try lowering this timeout value from the default of 80 seconds.

    Steve

  • Hi Steve,

    I solved the problem. The connection timeout was too long, yes, but changing its value (to 3) was not the main problem. I had changed the tick period value of the clock to 1s instead of 1ms (default in clock module settings from the SYS/BIOS). I changed it back again to 1ms and the timeout worked. In the .cfg stays "Connection timeout (seconds)", but it seems it doesnt work with seconds but with ticks. Is it not possible to change the clocks period to 1s without affecting the network? I need the clock each second and I want to avoid having a Swi each 1ms.

    Thanks a lot for your help!!
    Sara
  • Sara,

    Great that you are past that problem!

    I had changed the tick period value of the clock to 1s instead of 1ms (default in clock module settings from the SYS/BIOS). I changed it back again to 1ms and the timeout worked.

    Is it not possible to change the clocks period to 1s without affecting the network?

    The NDK's timer tick code (lltimer.c) assumes that its heartbeat Clock function will fire every 100ms.  By default, 1 tick = 1ms, and so the NDK's heartbeat period is set to 100 ticks.

    If you change the tick value in the Clock module, then this will definitely affect all of the timings in the stack.  So, if you want to do this, you must adjust the NDK's heartbeat accordingly (this is configurable via your *.cfg file, too.  See screen shot below).

    I must warn you, though, that changing the NDK's heartbeat is tricky business... it's easy to mess it up and affects things like TCP timers, for example.  Just a heads up, it's a "modify at your own risk" kind of thing :)

    Steve

  • Hi Steve,
    perfect explanation! Thanks a lot!
    Sara