Linux: is there a read or recv from socket with timeout?

前端 未结 5 1330
时光说笑
时光说笑 2020-11-27 10:42

How can I try to read data from socket with timeout? I know, select, pselect, poll, has a timeout field, but using of them disables \"tcp fast-path\" in tcp reno stack.

相关标签:
5条回答
  • 2020-11-27 10:53

    Here's some simple code to add a time out to your recv function using poll in C:

    struct pollfd fd;
    int ret;
    
    fd.fd = mySocket; // your socket handler 
    fd.events = POLLIN;
    ret = poll(&fd, 1, 1000); // 1 second for timeout
    switch (ret) {
        case -1:
            // Error
            break;
        case 0:
            // Timeout 
            break;
        default:
            recv(mySocket,buf,sizeof(buf), 0); // get your data
            break;
    }
    
    0 讨论(0)
  • 2020-11-27 10:55

    You can use the setsockopt function to set a timeout on receive operations:

    SO_RCVTIMEO

    Sets the timeout value that specifies the maximum amount of time an input function waits until it completes. It accepts a timeval structure with the number of seconds and microseconds specifying the limit on how long to wait for an input operation to complete. If a receive operation has blocked for this much time without receiving additional data, it shall return with a partial count or errno set to [EAGAIN] or [EWOULDBLOCK] if no data is received. The default for this option is zero, which indicates that a receive operation shall not time out. This option takes a timeval structure. Note that not all implementations allow this option to be set.

    // LINUX
    struct timeval tv;
    tv.tv_sec = timeout_in_seconds;
    tv.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
    
    // WINDOWS
    DWORD timeout = timeout_in_seconds * 1000;
    setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
    
    // MAC OS X (identical to Linux)
    struct timeval tv;
    tv.tv_sec = timeout_in_seconds;
    tv.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
    

    Reportedly on Windows this should be done before calling bind. I have verified by experiment that it can be done either before or after bind on Linux and OS X.

    0 讨论(0)
  • 2020-11-27 11:03

    // works also after bind operation for WINDOWS

    DWORD timeout = timeout_in_seconds * 1000;
    setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
    
    0 讨论(0)
  • 2020-11-27 11:05

    Install a handler for SIGALRM, then use alarm() or ualarm() before a regular blocking recv(). If the alarm goes off, the recv() will return an error with errno set to EINTR.

    0 讨论(0)
  • 2020-11-27 11:15

    LINUX

    struct timeval tv;
    tv.tv_sec = 30;        // 30 Secs Timeout
    tv.tv_usec = 0;        // Not init'ing this can cause strange errors
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv,sizeof(struct timeval));
    

    WINDOWS

    DWORD timeout = SOCKET_READ_TIMEOUT_SEC * 1000;
    setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
    

    NOTE: You have put this setting before bind() function call for proper run

    0 讨论(0)
提交回复
热议问题