关于connect函数超时太久的问题

解决方案思想: 通过把socket设置为非阻塞模式,然后通过select函数自己设置定时,检测套接字描述符是否可用。

windows端实现上代码: 过于粗略,仅呈思想
#include <winsock2.h>
#include <Windows.h>
#include <conio.h>
//#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>
//#include <sys/ioctl.h>
#include <stdarg.h>
//#include <fcntl.h>
#include <time.h>
int main(int argc, char *argv[])
{undefined
printf(“==main===\n”);fflush(stdout);
//Winsows下启用socket
WSADATA wsadata;
if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) {undefined
printf(“WSAStartup() fail\n”);fflush(stdout);
exit(0);
}
printf(“==WSAStartup ok ===\n”);fflush(stdout);
int sockClient = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addrSrv;
addrSrv.sin_addr.s_addr = inet_addr(argv[1]);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(atoi(argv[2]));
//fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK);
printf(“==goto ioctlsocket ok ===\n”);fflush(stdout);
unsigned long ul=1;
int ret=ioctlsocket(sockClient,FIONBIO,(unsigned long *)&ul); //设置成非阻塞模式
if(ret==SOCKET_ERROR) //设置失败
{undefined
printf(“socket ioctl error%d\n”, WSAGetLastError());fflush(stdout);
return -10;
}
printf(“==set sucess to connect===\n”);fflush(stdout);
int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
printf(“connect iRet is %d, errmsg:%s\n”, iRet, strerror(errno));
fflush(stdout); // 返回-1不一定是异常
if (iRet != 0)
{undefined
/*
if(errno != EINPROGRESS)
{undefined
printf(“connect error:%s\n”, strerror(errno)); fflush(stdout);
}
else
*/
{undefined
printf(“socket ===========\n”);
struct timeval tm = {5, 0};
fd_set wset, rset;
FD_ZERO(&wset);
FD_ZERO(&rset);
FD_SET(sockClient, &wset);
FD_SET(sockClient, &rset);
int time1 = time(NULL);
int n = select(sockClient + 1, &rset, &wset, NULL, &tm);
int time2 = time(NULL);
printf(“time gap is %d\n”, time2 – time1);fflush(stdout);
if(n < 0)
{
printf(“select error, n is %d\n”, n); fflush(stdout);
}
else if(n == 0)
{
printf(“connect time out\n”); fflush(stdout);
}
else if (n == 1)
{undefined
if(FD_ISSET(sockClient, &wset))
{
printf(“connect ok!\n”); fflush(stdout);
//fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK);
}
else
{
printf(“unknow error:%s\n”, strerror(errno)); fflush(stdout);
}
}
else
{undefined
printf(“oh, not care now, n is %d\n”, n);fflush(stdout);
}
}
}
printf(“I am here!\n”);fflush(stdout);
//ioctlsocket(sockClient, FIONBIO, &ul); //设置为阻塞模式 阻塞时间为timeout时间
getchar();
closesocket(sockClient);

WSACleanup();
return 0;

}

linux端实现:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <time.h>
int main(int argc, char *argv[])
{undefined
int sockClient = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addrSrv;
addrSrv.sin_addr.s_addr = inet_addr(argv[1]);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(atoi(argv[2]));
fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK);
int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
printf(“connect iRet is %d, errmsg:%s\n”, iRet, strerror(errno)); // 返回-1不一定是异常

if (iRet != 0)
{
if(errno != EINPROGRESS)
{undefined
printf(“connect error:%s\n”, strerror(errno));
}
else
{undefined
struct timeval tm = {5, 0};
fd_set wset, rset;
FD_ZERO(&wset);
FD_ZERO(&rset);
FD_SET(sockClient, &wset);
FD_SET(sockClient, &rset);
int time1 = time(NULL);
int n = select(sockClient + 1, &rset, &wset, NULL, &tm);
int time2 = time(NULL);
printf(“time gap is %d\n”, time2 – time1);
if(n < 0)
{
printf(“select error, n is %d\n”, n);
}
else if(n == 0)
{
printf(“connect time out\n”);
}
else if (n == 1)
{undefined
if(FD_ISSET(sockClient, &wset))
{
printf(“connect ok!\n”);
fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK);
}
else
{
printf(“unknow error:%s\n”, strerror(errno));
}
}
else
{undefined
printf(“oh, not care now, n is %d\n”, n);
}
}
}
printf(“I am here!\n”);
getchar();
close(sockClient);
return 0;
}

————————————————
版权声明:本文为CSDN博主「字正腔圆」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fengdijiang/article/details/116779987

本文出自:https://blog.csdn.net/fengdijiang/article/details/116779987