C++ connect()中的超时不工作
我正在使用此代码连接到服务器,但它没有等待我设置为超时的10秒。它在连接失败后立即返回C++ connect()中的超时不工作,c++,sockets,winsock,winsock2,C++,Sockets,Winsock,Winsock2,我正在使用此代码连接到服务器,但它没有等待我设置为超时的10秒。它在连接失败后立即返回 BOOL Connect(string server, int port, int timeout) { struct sockaddr_in RemoteHost; TIMEVAL Timeout; Timeout.tv_sec = timeout; Timeout.tv_usec = 0; int con_error = 0; #ifdef W32 WSA
BOOL Connect(string server, int port, int timeout)
{
struct sockaddr_in RemoteHost;
TIMEVAL Timeout;
Timeout.tv_sec = timeout;
Timeout.tv_usec = 0;
int con_error = 0;
#ifdef W32
WSADATA wsd;
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
DEBUG(L"Failed to load Winsock!\n");
return FALSE;
}
#endif
//create socket if it is not already created
if (s == SOCKET_ERROR)
{
//Create socket
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == SOCKET_ERROR)
{
DEBUG(L"Could not create socket");
return FALSE;
}
}
//setup address structure
if (inet_addr(server.c_str()) == INADDR_NONE)
{
struct hostent *he;
//resolve the hostname, its not an ip address
if ((he = gethostbyname(server.c_str())) == NULL)
{
//gethostbyname failed
DEBUG(L"gethostbyname() - Failed to resolve hostname\n");
return FALSE;
}
}
else//plain ip address
{
RemoteHost.sin_addr.s_addr = inet_addr(server.c_str());
}
RemoteHost.sin_family = AF_INET;
RemoteHost.sin_port = htons(port);
//set the socket in non-blocking
unsigned long iMode = 1;
int iResult = ioctlsocket(s, FIONBIO, &iMode);
if (iResult != NO_ERROR)
{
DEBUGP(L"ioctlsocket failed with error: %ld\n", iResult);
return FALSE;
}
//Connect to remote server
if ((con_error=connect(s, (struct sockaddr *)&RemoteHost, sizeof(RemoteHost))) < 0)
{
if (con_error != EINPROGRESS)
{
DEBUG(L"connect() failed");
return FALSE;
}
}
// restart the socket mode
iMode = 0;
iResult = ioctlsocket(s, FIONBIO, &iMode);
if (iResult != NO_ERROR)
{
DEBUGP(L"ioctlsocket failed with error: %ld\n", iResult);
return FALSE;
}
fd_set Write, Err;
FD_ZERO(&Write);
FD_ZERO(&Err);
FD_SET(s, &Write);
FD_SET(s, &Err);
// check if the socket is ready
select(0, NULL, &Write, &Err, &Timeout);
if (FD_ISSET(s, &Write))
{
return TRUE;
}
return FALSE;
}
BOOL连接(字符串服务器、int端口、int超时)
{
远程主机中的结构sockaddr_;
TIMEVAL超时;
Timeout.tv_sec=超时;
Timeout.tv_usec=0;
int con_错误=0;
#ifdefw32
水务署;
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
{
调试(L“加载Winsock失败!\n”);
返回FALSE;
}
#恩迪夫
//创建套接字(如果尚未创建)
如果(s==套接字错误)
{
//创建套接字
s=套接字(AF_INET、SOCK_STREAM、IPPROTO_TCP);
如果(s==套接字错误)
{
调试(L“无法创建套接字”);
返回FALSE;
}
}
//设置地址结构
if(inet\u addr(server.c\u str())==INADDR\u NONE)
{
结构宿主*he;
//解析主机名,而不是ip地址
if((he=gethostbyname(server.c_str())==NULL)
{
//gethostbyname失败
调试(L“gethostbyname()-解析主机名失败\n”);
返回FALSE;
}
}
else//普通ip地址
{
RemoteHost.sin_addr.s_addr=inet_addr(server.c_str());
}
RemoteHost.sin_family=AF_INET;
RemoteHost.sin_port=htons(端口);
//将插座设置为非阻塞状态
无符号长iMode=1;
int-iResult=ioctlsocket(s、FIONBIO和iMode);
如果(iResult!=无错误)
{
DEBUGP(L“ioctlsocket失败,错误:%ld\n”,iResult);
返回FALSE;
}
//连接到远程服务器
if((con_error=connect(s,(struct sockaddr*)和RemoteHost,sizeof(RemoteHost)))<0)
{
if(con_error!=EINPROGRESS)
{
调试(L“connect()失败”);
返回FALSE;
}
}
//重新启动套接字模式
iMode=0;
iResult=ioctlsocket(s、FIONBIO和iMode);
如果(iResult!=无错误)
{
DEBUGP(L“ioctlsocket失败,错误:%ld\n”,iResult);
返回FALSE;
}
fd_设置写入,错误;
FD_零(写入和写入);
FD_零(&Err);
FD_集,写入(&U);
FD_集,错误(&R);
//检查插座是否准备好
选择(0、空、写、错误和超时);
if(FD_ISSET(s和写入))
{
返回TRUE;
}
返回FALSE;
}
当套接字在目标系统上不可用时,它可能会发回并尝试连接失败。在这种情况下,winsock函数将立即返回-这是出于设计。当套接字在目标系统上不可用时,它可能会发回并尝试连接失败。在这种情况下,winsock函数将立即返回-这是出于设计。当套接字在目标系统上不可用时,它可能会发回并尝试连接失败。在这种情况下,winsock函数将立即返回-这是出于设计。当套接字在目标系统上不可用时,它可能会发回并尝试连接失败。在这种情况下,winsock函数将立即返回-这是出于设计。用于查找调用失败的原因<代码>连接成功时返回0,失败时返回套接字错误
您评论说,WSAGetLastError
返回以下状态:
无法立即完成的非阻塞套接字上的操作返回此错误,例如,当没有数据排队从套接字读取时,recv。这是一个非致命错误,应稍后重试该操作。WSAEWOULDBLOCK作为在非阻塞SOCK_流套接字上调用connect的结果报告是正常的,因为必须经过一段时间才能建立连接
设置的非阻塞套接字上的预期行为也是如此。用于找出调用失败的原因<代码>连接成功时返回0,失败时返回套接字错误
您评论说,WSAGetLastError
返回以下状态:
无法立即完成的非阻塞套接字上的操作返回此错误,例如,当没有数据排队从套接字读取时,recv。这是一个非致命错误,应稍后重试该操作。WSAEWOULDBLOCK作为在非阻塞SOCK_流套接字上调用connect的结果报告是正常的,因为必须经过一段时间才能建立连接
设置的非阻塞套接字上的预期行为也是如此。用于找出调用失败的原因<代码>连接成功时返回0,失败时返回套接字错误
您评论说,WSAGetLastError
返回以下状态:
无法立即完成的非阻塞套接字上的操作返回此错误,例如,当没有数据排队从套接字读取时,recv。这是一个非致命错误,应稍后重试该操作。WSAEWOULDBLOCK作为在非阻塞SOCK_流套接字上调用connect的结果报告是正常的,因为必须经过一段时间才能建立连接
设置的非阻塞套接字上的预期行为也是如此。用于找出调用失败的原因<代码>连接成功时返回0,失败时返回套接字错误
您评论说,WSAGetLastError
返回以下状态:
无法立即完成的非阻塞套接字上的操作返回此错误,例如,当没有数据排队从套接字读取时,recv。这是一个非致命错误,应稍后重试该操作。WSAEWOULDBLOCK作为在非阻塞SOCK_流套接字上调用connect的结果报告是正常的,因为必须经过一段时间才能建立连接
非阻塞袜子上的预期行为也是如此