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

Asked

Viewed 438 times

5

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

Code example:

//  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 until give time-out, 3 seconds then gather everything received in a varivael and return?

1 answer

8


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

Note: fd = file Descriptor, I will call it descriptor

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

FD_ZERO: Takes as parameter an fd_set and initializes it

FD_SET: Takes as parameter a descriptor(your socket) and inserts it into the specified fd_set

FD_ISSET: Rebece as parameter a descriptor and tests if it is contained in fd_set

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

sec: time in seconds

usec: the time in microseconds

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

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

In windows the function is in the header:winsock2.h(remembering that it replaces the winsock.h), already in linux you must include sys\select.h and sys\time.h, I think these are enough, but 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 of use:

    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 on github but I didn’t use the timeout, I edited it now and I didn’t test the code because I’m at work and I can’t test it here, but this should work, if not, should at least direct you to the answer.

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

client server

Both use timeout, tested only in windows.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.