2009年8月12日星期三

connect_with_timeout

/*
* @brief connect to an address with a user timeout
* @param fd file descriptor previously opened with "socket()"
* @param addr the address to connect to
* @param seconds the number of seconds to wait wait on theconnection
* @returns 0 on success, otherwise -1 and errno set to the correct error
* Remember to properly handle EINTR
*/
int connect_with_timeout(int fd, struct sockaddr * addr, unsigned seconds )
{
int ret;
int opt;
fd_set fdset;
struct timeval tv;

/* Set the socket to nonblocking first */
opt = fcntl(fd, F_GETFL, NULL);
opt |= O_NONBLOCK;
fcntl(fd, F_SETFL, opt);

for(;;)
{
/* open the connection */
ret = connect(fd, addr, sizeof(struct sockaddr));
if( ret == 0 )
{
/* connection worked */
break;
}
else if( errno != EINPROGRESS )
{
/* no connection yet, and errno is not EINPROGRESS
* this means we have some sort of a connection error
*/
break;
}

opt = 0;
tv.tv_sec = seconds;
tv.tv_usec = 0;

FD_ZERO(&fdset);
FD_SET(fd, &fdset);

/* wait for something to see if the socket becomes
* writeable ( it will become writable on error as well */
ret = select(fd+1, NULL, &fdset, NULL, &tv);
if ( ret == 0)
{
errno = ETIMEDOUT;
ret = -1;
break;
}
else if( ret == -1 )
{
break;
}
}

/* Set socket back to blocking mode */
opt = fcntl(fd, F_GETFL, NULL);
opt &= (~O_NONBLOCK);
fcntl(fd, F_SETFL, opt);

//#if __DEBUG__
/* debug junk for those that want to see how this works */
if( ret == 0 )
{
printf("Returning Success\n");
}
else
{
printf("Returning
Failure(%d),errno=%d,%s\n",ret,errno,strerror(errno));
}
//

没有评论: