SO_RCVTIMEO在VPN环境中不起作用

时间:2018-03-05 03:46:32

标签: linux network-programming

我有一个非常简单的套接字服务器/客户端应用程序,可以相互访问 心跳每30秒通过VPN连接, 而vpn突然破了哪个应该导致socket 客户端recv返回-1,但在vpn的情况下,阻塞recv不会立即返回-1,我不知道为什么会这样,几分钟后左右 recv返回-1),所以我尝试使用SO_RCVTIMEO如下:

struct timeval tout ;
tout.tv_sec = 35 ;
tout.tv_usec = 0 ;
int setRcvTimeO = 0 ;
setRcvTimeO = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tout, sizeof(tout)) ;
while( 1 ){
    int nread = 0  ;
    char strdata[1024]={0},strtmp[32]={0} ;
    if ( (nread = readnx(fd,strtmp,20)) <=  0){  
        close(fd) ;
        if( doConnectServer() ){
            doLoginServer() ;
        }
        sleep(3) ;
        continue ;
    }
    doSomeThing(strtmp) ;
} //while 

正如您所看到的,我尝试在35秒后无法接收任何服务器时重新连接到服务器 数据,这项工作在局域网中,但在vpn环境中,它仍然没有这样做, 在35秒后,recv仍然不会返回-1。

Linux内核无法知道fd通过vpn连接被破坏导致这个问题,有什么我可以做的,我可以重新连接服务器而vpn 突然崩溃了?!

编辑:

ssize_t readnx(int fd, void *buffer, size_t n)
{
    ssize_t numRead;                    /* # of bytes fetched by last read() */
    size_t totRead;                     /* Total # of bytes read so far */
    char *buf;

    buf = (char*) buffer;               /* No pointer arithmetic on "void *" */
    for (totRead = 0; totRead < n; ) {
        numRead = recv(fd, buf, n - totRead,MSG_NOSIGNAL);

        if (numRead == 0)               /* EOF */
            return totRead;             /* May be 0 if this is first read() */
        if (numRead == -1) {
            if (errno == EINTR)
                continue;               /* Interrupted --> restart read() */
            else
                return -1;              /* Some other error */
        }
        totRead += numRead;
        buf += numRead;
    }
    return totRead;                     /* Must be 'n' bytes if we get here */
}

0 个答案:

没有答案