[转]windows下设置socket的connect超时
原文地址:http://www.cnblogs.com/BloodAndBone/archive/2012/05/22/2513338.html
变相的实现connect的超时,我要讲的就是这个方法,原理上是这样的:
1.建立socket
2.将该socket设置为非阻塞模式
3.调用connect()
4.使用select()检查该socket描述符是否可写(注意,是可写)
5.根据select()返回的结果判断connect()结果
6.将socket设置为阻塞模式(如果你的程序不需要用阻塞模式的,这步就省了,不过一般情况下都是用阻塞模式的,这样也容易管理)
// widonws: 默认设置socket TCP client connect为阻塞模式 void TcpConnect(char* strIP, UINT nPort) { struct sockaddr_in serverAddress; SOCKET hSocket = NULL; hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if( hSocket==INVALID_SOCKET) { return; } memset(&serverAddress, 0, sizeof(serverAddress)); serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = inet_addr(strIP); serverAddress.sin_port = htons((short)nPort); int iTimeOut = 3000; setsockopt(hSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&iTimeOut,sizeof(iTimeOut)); setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char*)&iTimeOut,sizeof(iTimeOut)); if( SOCKET_ERROR==connect(hSocket, (sockaddr*)&serverAddress, sizeof(serverAddress)) ) { closesocket(hSocket); DWORD gle = WSAGetLastError(); return; } char buff[] = "hello"; int sl=::send(hSocket,(char*)buff, sizeof(buff), 0); if( sl<0 ) { closesocket(hSocket); return ; } closesocket(hSocket); } // widonws: 设置socket TCP client connect非阻塞模式 void SockSelect(char* strIP, UINT nPort) { SOCKET/*int*/ sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(sockfd < 0) { return; } struct sockaddr_in serv_addr; //以服务器地址填充结构serv_addr serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(strIP); serv_addr.sin_port = htons(nPort); int error = -1; int len = sizeof(int); timeval tm; fd_set set; unsigned long ul = 1; ioctlsocket(sockfd, FIONBIO, &ul); //设置为非阻塞模式 bool ret = false; if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) { tm.tv_sec = 3; tm.tv_usec = 0; FD_ZERO(&set); FD_SET(sockfd, &set); if( select(sockfd+1, NULL, &set, NULL, &tm) > 0) { getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *)&error, /*(socklen_t *)*/&len); if(error == 0) ret = true; else ret = false; } else ret = false; } else ret = true; ul = 0; ioctlsocket(sockfd, FIONBIO, &ul); //设置为阻塞模式 if(!ret) { closesocket( sockfd ); fprintf(stderr , "Cannot Connect the server!/n"); return; } fprintf( stderr , "Connected!/n"); char buff[] = "hello"; int sl=::send(sockfd,(char*)buff, sizeof(buff), 0); closesocket( sockfd ); }