socket中connect的默认超时时间

1.connect函数原型:

# include < sys/ types. h> /* See NOTES */
# include < sys/ socket . h>
int connect ( int sockfd, const struct sockaddr * serv_addr, socklen_t addrlen) ;

RETURN VALUE:
       If  the  connection  or  binding  succeeds,  zero  is  returned.   On error, -1 is returned, and errno is set appropriately.


 
2.默认情况下,connect函数的超时情况:
引用: http://blog.chinaunix.net/u1/53217/showart_710651.html  
《UNP》第一卷 第三版 P85-P86指出伯克利系统的超时时限为75s, Solaris9超时时限为4分钟,所以一般认为是75s到几分钟不等,而我测试的时限为 189s(Linux Kernel 2.6.24),SYN6次重传~~
我的FC8 Linux Kernel  2.6.23.1-42,测试超时时间为 189s

3.支持重试的连接(APUE2 16.4节)

#include < stdio. h>
#include < stdlib. h>
#include < netinet/in . h>
#include < sys/socket. h>
#include < string. h>
#include < fcntl. h>

#define SRV_PORT 65530

#define MAXSLEEP 128

#define errexit( msg) do {perror( msg) ; exit( EXIT_FAILURE) ; } while ( 0)

/* * *
 * max sleep time = 1 + 2 + 4 + 8 + 18 + . . . + 64 = 2^7 - 1 = 127 ( s)
 * * * /
int connect_retry( int sockfd, const struct sockaddr * srv_addr, socklen_t addrlen)
{
        int nsec;

        for ( nsec = 1; nsec < = MAXSLEEP; nsec < < = 1)
        {
                if ( connect( sockfd, srv_addr, addrlen) = = 0)
                        return 0; /* connection accepted * /
                if ( nsec < = MAXSLEEP / 2) /* < = 2^7 /2 = 64* /
                        sleep ( nsec) ;
        }

        return - 1

}

int main( int argc, char * argv[ ] )
{
        int sockfd;
        struct sockaddr_in srv_addr;
        socklen_t addrlen;

        int flags;

        if ( argc ! = 2) {
                printf( "Usage: %s <ip>/n" , argv[ 0] ) ;
                exit( 1) ;
        }

        if ( ( sockfd = socket( AF_INET, SOCK_STREAM, 0) ) < 0)
                errexit( "socket error" ) ;

        addrlen = sizeof ( struct sockaddr) ;
        memset( & srv_addr, 0, addrlen) ;
        srv_addr. sin_family = AF_INET;
        srv_addr. sin_addr. s_addr = inet_addr( argv[ 1] ) ;
        srv_addr. sin_port = htons( SRV_PORT) ;

        flags = fcntl( sockfd, F_GETFL, 0) ;
        fcntl( sockfd, F_SETFL, flags | O_NONBLOCK) ;

        printf( "connecting.../n" ) ;
        time_t t = time( NULL) ;
        //if ( connect( sockfd, ( struct sockaddr * ) & srv_addr, addrlen) < 0) {
        if ( connect_retry( sockfd, ( struct sockaddr * ) & srv_addr, addrlen) < 0) {
                printf( "interval = %d/n" , time( NULL) - t) ;

                close(sockfd);
                errexit( "connect error" ) ;
        }
        close(sockfd);

       exit( 0) ;
}


说明:

1. 在阻塞情况下,connect函数在 Linux Kernel  2.6.23.1-42,测试超时时间为 189s。

2. 在用上述方法设置的非阻塞情况下,connect_retry 函数中,如果调用connect失败,进程就会休眠一小段时间然后在尝试连接,每循环一次增加每次尝试的延迟, 直到最大延迟为 127s。

你可能感兴趣的:(linux,socket,struct,Solaris,测试,binding)