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");
}
}