1.置socket为nonblock 。
2.连接,返回-1,errno为EINPROGRESS 。
3.使用select监控读写事件。
4.如果触发读写事件,重新connect,应返回-1,errno为EISCONN,表明连接成功。
Q :为何要重新connect ?
A :连接失败也可能触发读写事件,重新connect用于确定socket状态是否已连接。
int sockfd = socket(AF_INET,SOCK_STREAM,0) ;
fcntl(sockfd,F_SETFL,O_NONBLOCK|fcntl(sockfd,F_GETFL,0) ) ;
sockaddr_in addr = {0} ;
addr.sin_family = AF_INET ;
addr.sin_addr = inet_addr("192.168.0.1") ;
addr.sin_port = htons(80);
if ( connect(sockfd,addr,sizeof(addr)) < 0 && errno !=EINPROGRESS)
{
//connect failed
close(sockfd) ;
return -1 ;
}
struct timeval timeout= {5,0} ;
fd_set rs,ws ;
FD_ZERO(&rs) ;
FD_ZERO(&ws) ;
FD_SET(sockfd,&rs) ;
FD_SET(sockfd,&ws) ;
if ( select(sockfd+1,&rs,&ws,NULL,&timeout) < 1 )
{
//timeout
}
else
{
if ( connect(sockfd,addr,sizeof(addr)) < 0 && errno !=EISCONN)
{
//connect failed
}
//success
}