Unix网络编程之给阻塞式函数设定超时限定

来源:互联网 发布:淘宝买日系钢笔的店铺 编辑:程序博客网 时间:2024/05/16 18:33

1.给read函数设定超时时间。

代码:

int read_timeout(int fd,unsigned int wait_seconds){        int ret = 0;        if(wait_seconds > 0){                fd_set set;                struct timeval timeout;                FD_ZERO(&set);                FD_SET(fd,&set);                timeout.tv_sec = wait_seconds;                timeout.tv_usec = 0;                do{                        ret = select(fd+1,&set,NULL,NULL,&timeout);                }while(ret < 0 && errno == EINTR);                if(ret == 0){                        ret = -1;                        errno = ETIMEDOUT;                }                else if(ret == 1)                        ret = 0;        }        return ret;}

2.给write函数设定超时时间。

代码:

int write_timeout(int fd,unsigned int wait_seconds){        int ret = 0;        if(wait_seconds > 0){                fd_set set;                struct timeval timeout;                FD_ZERO(&set);                FD_SET(fd,&set);                timeout.tv_sec = wait_seconds;                timeout.tv_usec = 0;                do{                        ret = select (fd+1,NULL,&set,&timeout);                }while(ret <0 && errno == EINTR);                if(ret == 0){                        ret = -1;                        errno == ETIMEDOUT;                }                else if(ret == 1){                        ret = 0;                }        }        return ret;}

3.给accept函数设定超时限定。

代码:

int accept_timeout(int fd,struct sockaddr_in *addr,unsigned int wait_seconds){        int ret = 0;        socklen_t addrlen = sizeof(struct sockaddr_in);        if(wait_seconds > 0){                fd_set set;                struct timeval timeout;                FD_ZERO(&set);                FD_SET(fd,&set);                timeout.tv_sec = wait_seconds;                timeout.tv_usec = 0;                do{                        ret = select(fd+1,&set,NULL,NULL,&timeout);                }while(ret < 0 && errno == EINTR);                if(ret == -1)                        return -1;                else if(ret == 0){                        errno = ETIMEDOUT;                }        }        if(addr != NULL){                accept(fd,(struct sockaddr*)addr,&addrlen);        }else            ret = accept(fd,NULL,NULL);        if(ret == -1)                ERR_EXIT("accept");        return ret;}

4.给connect 函数设定超时限定。

代码:

int connect_timeout(int fd,struct sockaddr_in *addr,unsigned int wait_seconds){        int ret;        socklen_t addrlen = sizeof(struct sockaddr_in);        if(wait_seconds > 0){                activate_nonblock(fd);        }        ret = connect(fd,(struct sockaddr*)addr,addrlen);        if(ret < 0&& errno == EINPROGRESS){                fd_set set;                struct timeval timeout;                FD_ZERO(&set);                FD_SET(fd,&set);                timeout.tv_sec = wait_seconds;                timeout.tv_usec = 0;                do{                        ret = select(fd+1,NULL,&set,NULL,&timeout);                }while(ret < 0 && errno == EINTR);                if(ret == 0){                        ret = -1;                        errno = ETIMEDOUT;                }else if(ret < 0)                        return -1;                 else if(ret ==1)                {                        int err;                        socklen_t socklen = sizeof(err);                        int sockoptret = getsockopt(fd,SOL_SOCKET,SO_ERROR,&err,&socklen);                        if(err == 0){                                ret = 0;                        }else{                                errno = err;                                ret = -1;                        }                }        }        if(wait_seconds > 0)        {                deactivate_nonblock(fd);        }        return ret;}

5.给一个fd设置阻塞还是非阻塞的函数:

(1)设定fd为非阻塞

void deactivate_nonblock(int fd){        int ret;        int flags = fcntl(fd,F_GETFL);        if(flags ==-1)                ERR_EXIT("fcntl");        flags &= ~O_NONBLOCK;        ret = fcntl(fd,F_SETFL,flags);        if(ret == -1)                ERR_EXIT("fcntl");}
(2)设定fd为阻塞:

void activate_nonblock(int fd){        int ret;        int flags = fcntl(fd,F_GETFL);        if(flags == -1){                ERR_EXIT("fcntl");        }        flags |= O_NONBLOCK;        ret = fcntl(fd,F_SETFL,flags);        if(ret == -1){                ERR_EXIT("fcntl");        }}



0 0
原创粉丝点击