0

I am making a multi-threaded TCP server, when I use recv() in the threads, they do not update/execute/run infinitely (looping), unless recv() actually receives some data.

Here is a code snippet from inside the loop.

if( seconds < 15 ){
    printf("%f seconds passed: \r", seconds);

    if ( (read_size = recv(sock , client_message , 512 , 0)) > 0 )
    {
      //Send the message back to client
      reply_message = client_message;
      (void)write(sock, reply_message, strlen(reply_message));
    }

}else{
    // ... blah blah blah
}

If I comment out the internal IF statement, the thread runs & outputs printf() as fast as it can. When the IF statement is included, the thread waits on recv() and will not update ( printf() isn't printed ) until recv() has received data :/

Any ideas?

user207421
  • 305,947
  • 44
  • 307
  • 483
MissionGuy07
  • 31
  • 1
  • 5
  • 6
    Well that's what it's supposed to do. What were you expecting it to do? – univerio May 09 '15 at 02:56
  • It should continuously print out seconds passed up to 15 seconds while also receiving data. However, when recv() is used it doesn't and other conditional statements based of the seconds variable aren't executing because of recv() halting the thread. – MissionGuy07 May 09 '15 at 03:02
  • 2
    You want to combine `select` with a 1-second timeout with `recv`. Also you want to set the socket to non-blocking. Also you need to handle short reads... – Nemo May 09 '15 at 03:04
  • Related: http://stackoverflow.com/q/2295737/694576 – alk May 09 '15 at 08:43
  • '`recv()` halting [you mean 'blocking'] the thread' is what's supposed to happen. Your question remains unclear. – user207421 Jan 18 '16 at 01:12

1 Answers1

1

From recv(2) - Linux man page (see here):

If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking (see fcntl(2)), in which case the value -1 is returned and the external variable errno is set to EAGAIN or EWOULDBLOCK. The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested.

So it's the way how recv works. If you want it to return immediately you should use non-blocking mode (see fcntl and select desriptions).

// sock is the socket you want to make non-blocking
int status = fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);

// handle the error
if(status == -1) {
    ...
}

If you want to check if there anything to read in socket

int count = 0;
ioctl(sock, FIONREAD, &count);

count is the number of bytes available in the socket

Nikolay K
  • 3,770
  • 3
  • 25
  • 37