套接字超时

套接字超时

一、使用SIGALRM为connect 设置超时

signal  捕捉到alarm信号之后会中断connect函数,导致返回值为EINTR,因此可提前设置connect超时返回,而不用等到最长 75s的connect原始超时时长

1、Signal 返回值 为  typede void Sigfunc(int);    -- 可以保存和恢复旧的信号处理函数

2、alarm(); 可覆盖之前的定时,返回值为 之前定时的剩余时间,返回0表示之前未设置定时

3、connect()  返回 < 0,设置为失败,超时; 若成功, == 0;connect失败后需关闭close(sockfd);并重新 socket() 获取套接字

/* include connect_timeo */
#include    "unp.h"

static void connect_alarm(int);

int
connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec)
{
    Sigfunc *sigfunc;
    int     n;  

    sigfunc = Signal(SIGALRM, connect_alarm);
    if (alarm(nsec) != 0)
        err_msg("connect_timeo: alarm was already set");

    if ( (n = connect(sockfd, saptr, salen)) < 0) {
        close(sockfd);
        if (errno == EINTR)
            errno = ETIMEDOUT;
    }   
    alarm(0);                   /* turn off the alarm */
    Signal(SIGALRM, sigfunc);   /* restore previous signal handler */

    return(n);
}

static void
connect_alarm(int signo)
{
    return;     /* just interrupt the connect() */
}
/* end connect_timeo */

void
Connect_timeo(int fd, const SA *sa, socklen_t salen, int sec)
{
    if (connect_timeo(fd, sa, salen, sec) < 0)
        err_sys("connect_timeo error");             // 出错或者超时 都 < 0

    // 连接成功 connect_timeo 返回 0
}

二、使用SIGALRM为connect 设置超时