int test_tcp_connect(const char* dst, unsigned short port)
{
struct sockaddr_in addr;
int flags;
fd_set writefds;
int nfds;
struct timeval timeout;
int result;
int tcp_sd;
if(NULL == dst)
return -1;
tcp_sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(tcp_sd < 0)
return -2;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = net_inet_aton(dst);
addr.sin_port = htons(port);
printf("hilink tcp connect ip: %s port = %d\r\n",dst,port);
/*Set as nonblocking*/
flags = fcntl(tcp_sd, F_GETFL, 0);
fcntl(tcp_sd, F_SETFL, flags | O_NONBLOCK);
int reuse = 1;
if(setsockopt(tcp_sd, SOL_SOCKET, SO_REUSEADDR,(const char *) &reuse, sizeof( reuse ) ) != 0 )
{
close(tcp_sd);
printf("tcp set SO_REUSEADDR failed\n");
return -2;
}
if(connect(tcp_sd, (const struct sockaddr_in *)&addr, sizeof(addr)) != 0 \
&& errno != EINPROGRESS)
{
printf("dna_connect failed %d\n", tcp_sd);
goto err;
}
nfds = tcp_sd + 1;
timeout.tv_sec = 3; //Waiting 2s to connect to tcp server
timeout.tv_usec = 0;
FD_ZERO(&writefds);
FD_SET(tcp_sd, &writefds);
result = select(nfds, NULL, &writefds, NULL, &timeout);
//dna_printf("hilink tcp Result %d %d\r\n", result, FD_ISSET(tcp_sd, &writefds));
if(result == 0)
goto err;
else if(result > 0)
{
if(FD_ISSET(tcp_sd, &writefds))
{
int error = 0;
int len = sizeof (error);
result = getsockopt(tcp_sd,SOL_SOCKET,SO_ERROR,&error, &len);
printf( "getsockopt fail,result =%d error=%d\r\n",result,error);
if(result < 0)
{
printf( "getsockopt fail,connected fail \n");
goto err;
}
if(error != 0)
{
printf("error = %d , connected fail \r\n",error);
goto err;
}
return tcp_sd;
}
}
err:
close(tcp_sd);
return -2;
}
1 要设置为非阻塞的模式,阻塞模式connect 大多数设计都是75s
2 通过select 判断等待套接字可读或可写,如果可以读或写;再通过 getsockopt 处理SO_ERROR,如果小于0,则连接失败,考虑不同平台的兼容性,(Berkeley getsockopt 返回为0,错误在码SO_ERROR里,Solaris 则会返回-1),所以还需要进一步判断错误码,具体可以参考书籍《UNIX网络编程卷1:套接字API(第三版) p352》
版权声明:本文为wang112031原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。