int my_tcp_connect(char *host_name, int port, int *sd, int timeout){
struct addrinfo hints;
struct addrinfo *res;
int result;
char *port_str=NULL;
int flags=0;
fd_set rfds;
fd_set wfds;
struct timeval tv;
int optval;
socklen_t optlen;
memset(&hints,0,sizeof(hints));
hints.ai_family=PF_INET;
hints.ai_socktype=SOCK_STREAM;
asprintf(&port_str,"%d",port);
result=getaddrinfo(host_name,port_str,&hints,&res);
if(result!=0){
/*printf("GETADDRINFO: %s (%s) = %s\n",host_name,port_str,gai_strerror(result));*/
return ERROR;
}
/* create a socket */
*sd=socket(res->ai_family,SOCK_STREAM,res->ai_protocol);
if(*sd<0){
freeaddrinfo(res);
return ERROR;
}
/* make socket non-blocking */
flags=fcntl(*sd,F_GETFL,0);
fcntl(*sd,F_SETFL,flags|O_NONBLOCK);
/* attempt to connect */
result=connect(*sd,res->ai_addr,res->ai_addrlen);
/* immediately successful connect */
if(result==0){
result=OK;
/*printf("IMMEDIATE SUCCESS\n");*/
}
/* connection error */
else if(result<0 && errno!=EINPROGRESS){
result=ERROR;
}
/* connection in progress - wait for it... */
else{
do{
/* set connection timeout */
tv.tv_sec=timeout;
tv.tv_usec=0;
FD_ZERO(&wfds);
FD_SET(*sd,&wfds);
rfds=wfds;
/* wait for readiness */
result=select((*sd)+1,&rfds,&wfds,NULL,&tv);
/*printf("SELECT RESULT: %d\n",result);*/
/* timeout */
if(result==0){
/*printf("TIMEOUT\n");*/
result=ERROR;
break;
}
/* an error occurred */
if(result<0 && errno!=EINTR){
result=ERROR;
break;
}
/* got something - check it */
else if(result>0){
/* get socket options to check for errors */
optlen=sizeof(int);
if(getsockopt(*sd,SOL_SOCKET,SO_ERROR,(void *)(&optval),&optlen) < 0){
result=ERROR;
break;
}
/* an error occurred in the connection */
if(optval!=0){
result=ERROR;
break;
}
/* the connection was good! */
/*
printf("CONNECT SELECT: ERRNO=%s\n",strerror(errno));
printf("CONNECT SELECT: OPTVAL=%s\n",strerror(optval));
*/
result=OK;
break;
}
/* some other error occurred */
else{
result=ERROR;
break;
}
}while(1);
}
freeaddrinfo(res);
return result;
}
一个很标准的例子,输入为ip,端口号和超时时长,返回socket的文件描述符