我的本意是通过select超时来快速返回socket失败的问题,代码如下
但是我现在的IP都是不可用的ping不通,为什么select总是返回1 呢?
/******************************
* Time out for connect()
* Write by Kerl W
******************************/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#define TIME_OUT_TIME 10 //connect超时时间20秒
#define true 1
#define false 0
int main(int argc , char **argv)
{
int flags, error = 0,len,ret;
struct sockaddr_in serv_addr;
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
exit(1);
//以服务器地址填充结构serv_addr
len = sizeof(int);
struct timeval tm;
fd_set set;
unsigned long ul = 1;
//设置sockaddr_in结构体中相关参数
serv_addr.sin_family = AF_INET; //地址族 IPV4
serv_addr.sin_port = htons(80); //设置为要连接的服务器的端口号(short数据转化为网络数据)
serv_addr.sin_addr.s_addr = inet_addr("192.168.3.64"); //设置服务器的IP地址(字符串转化为整形)
// ioctl(sockfd, FIONBIO, &ul); //设置为非阻塞模式
flags = fcntl(sockfd, F_GETFL, 0);
if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0){
//close(m_socket);
return -2;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <0)
{
if (errno != EINPROGRESS){
printf("errno != EINPROGRESS\n");
return -1;
}
tm.tv_sec == TIME_OUT_TIME;
tm.tv_usec = 0;
FD_ZERO(&set);
FD_SET(sockfd, &set);
ret = select(sockfd+1, NULL, &set, NULL, &tm);
if( ret > 0)
{
printf("ret is %d fd_set = %d sockfd = %d\n",ret,sizeof(fd_set),sockfd);
// getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
len = sizeof(error);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0){
return -1; /* Solaris pending error */
}
}
else if(ret == 0)
{
close(sockfd);
printf( "Connect time out !\n");
return -1;
}
/* 恢复套接字的文件状态标志并返回 */
fcntl(sockfd, F_SETFL, flags); /* restore file status flags */
if (error) {
close(sockfd); /* just in case */
errno = error;
return(-2);
}
printf( "Connected!\n");
}
}