0


关于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[])
{
printf("==main===\n");fflush(stdout);
//Winsows下启用socket
WSADATA wsadata;
if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) {
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) //设置失败
{
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)
{
/

if(errno != EINPROGRESS)
{
printf("connect error:%s\n", strerror(errno)); fflush(stdout);
}
else
*/
{
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)
{
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
{
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[])
{
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)
{
printf("connect error:%s\n", strerror(errno));
}
else
{
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)
{
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
{
printf("oh, not care now, n is %d\n", n);
}
}
}
printf("I am here!\n");
getchar();
close(sockClient);
return 0;
}

http://cache.baiducontent.com/c?m=YG5_oMGpXgIPmbhjnGo8iuOkg6r5BG-IOYPiHxsHndO7uml0F8mDauTl7Kgmpr0Hw3IFclRUo4wjnRZZTypvCOJrTUVpllsN8-It0LlsonT5YhmtpZpnciKQ0rrQlEtLEk4J2I7qmec2SC0QyazL1q&p=cb769a47898c13ff57ec966d5b40&newp=9c6fd10586cc40ad01a2c7710f5e92695d0fc20e3bd3da01298ffe0cc4241a1a1a3aecbf2c251b02d9c277620aad4e5ceff132743d0034f1f689df08d2ecce7e76c7&s=45c48cce2e2d7fbd&user=baidu&fm=sc&query=windows+connect&qid=89bd31ba0043d24b&p1=2

标签: 积累

本文转载自: https://blog.csdn.net/fengdijiang/article/details/116779987
版权归原作者 字正腔圆 所有, 如有侵权,请联系我们删除。

“关于connect函数超时太久的问题(不同系统的默认超时时长不一,但都很久)”的评论:

还没有评论