How to implement timeout on recv () in socket.h

5

I'm wondering if there is any function to put a timeout together with recv () using Socket.h .

Code sample:

//  Variaveis
UINT    in_socket_handler;
struct  sockaddr_in server;
//  Cria o Socket
in_socket_handler           =   socket(AF_INET, SOCK_STREAM,    0);

//
//  Informa para conectar no server
//  IP do servidor
server.sin_family           =   AF_INET;

//  Familia ARPANET
server.sin_addr.s_addr      =   inet_addr(as_host);

//  Porta - hton = host to network short (2bytes) ou htons para mais
server.sin_port             =   htons(an_port);

//  Limpa varivavel
memset  ( &(server.sin_zero), 0x00, sizeof(server.sin_zero));

//  Inicia comunicacao com server
if ( connect(in_socket_handler, (struct sockaddr *) &server,    sizeof (server)) <  0 )
{
    //  Se ocorreu uma falha
    ln_connection_status            =   9;
}
else
{
    //  conectou com sucesso
    ln_connection_status            =   0;
}


// Recebe
int  =  recv( in_socket_handler, buffer, 4096, 0);

Someone knows if there is any way to receive it until it is time-out, 3 seconds, then it joins everything received in a varivael and returns?

    
asked by anonymous 02.08.2016 / 22:02

1 answer

8

You can use the select function described here: select (2) - Linux manual and here: windows API function

Note: fd = file descriptor, I'll call it descriptor

The select function works over several descriptors at the same time, it tests with a timeout if a given operation is available on the given descriptors, such descriptors are contained in fd_set structures, this structure is manipulated by the macros:

FD_ZERO : Receives as parameter a fd_set and initializes it

FD_SET : Receives as parameter a descriptor (its socket) and inserts it in the specified fd_set

FD_ISSET : Overrides as a parameter descriptor and tests whether it is contained in fd_set

The function receives three fd_set's: the first contains the descriptors that will be used to test read operations, the second descriptors are for testing write operations, and the third ones for error checking. The first parameter of the function is a number that indicates the highest fd that is contained in all fd_set's passed plus one (this is ignored in windows). The last parameter is a timeval structure that has two fields:

sec : the time in seconds

usec : the time in microseconds

The two together specify the time the function should wait until an operation is available. If you pass null the function will lock until at least one operation is available.

When the function returns the last fd_set's will only contain the fd's that are available for the requested operation.

In windows the function is in the header: winsock2.h (remembering that it replaces winsock.h ), already in linux you must include sys\select.h and sys\time.h , I think these are sufficient, however the link I reported uses:

/* According to POSIX.1-2001 */
#include <sys/select.h>

/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

Example usage:

    enum OPERATION
    {
        READ = 0,
        WRITE,
        EXCEPTION
    };

    bool testOperation(uint16 sock, OPERATION operation, long milliseconds)
    {
        int r;
        //o primeiro membro da struct é o tempo em segundos e o segundo é o tempo em microsegundos
        struct timeval timeout = { milliseconds/1000, 0};
        fd_set fds;

        FD_ZERO(&fds);
        FD_SET(sock, &fds);

        switch (operation)
        {
        case READ:
            //observe que é possível passar fd_set's nulos
            r = select(sock + 1, &fds, NULL, NULL, &timeout);
            break;
        case WRITE:
            r = select(sock + 1, NULL, &fds, NULL, &timeout);
            break;
        case EXCEPTION:
            r = select(sock + 1, NULL, NULL, &fds, &timeout);
            break;
        }

        if (r == SOCKET_ERROR){/*erro*/}

        //operação está disponível
        if (FD_ISSET(sock, &fds))
            return true;

        return false;
    }

This is a code I had in github but I did not use the timeout, I edited now and I did not test the code because I'm at work and here I can not test it, but this should work, if not, it should at least direct you to the answer.

EDITED I created two snippets in github to demonstrate use with two client / server programs:

client server

The two use timeout, I only tested on windows.

    
09.11.2016 / 17:00