如何设置connect超时?

LiSCode 2009-06-23 03:41:18
代码如下:

// 装入Winsock然后连接服务器
__declspec (dllexport) int LoadWinsockM(HWND hWnd,char *szIP,HWND m_child_wnd)
{
WSADATA wsd;
DWORD dwLen;
int nRet,nZero;
LPBYTE pBuf;
WSAPROTOCOL_INFO Protocol;
char szMessage[81];
if (WSAStartup(0x202,&wsd) != 0)
{
MessageBox(NULL,"hehe","Client Socket Error",MB_OK);
return 0;
}
dwLen = 0;
nRet = WSAEnumProtocols(NULL,NULL,&dwLen);
if (nRet == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAENOBUFS)
return 0;
}
pBuf = malloc(dwLen);
nRet = SelectProtocols(SETFLAGS,NOTSETFLAGS,(LPWSAPROTOCOL_INFO)pBuf,&dwLen,&Protocol);
free(pBuf);
m_data[m_index].sClient = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_IP,NULL,0,SOCK_STREAM);
if (m_data[m_index].sClient == INVALID_SOCKET)
return 1;
nZero = 0;
setsockopt(m_data[m_index].sClient,SOL_SOCKET,SO_RCVBUF,(char *)&nZero,sizeof(nZero));
m_data[m_index].server.sin_family = AF_INET;
m_data[m_index].server.sin_port = htons(m_data[m_index].port);
m_data[m_index].server.sin_addr.s_addr = inet_addr(szIP);

if (connect(m_data[m_index].sClient,(struct sockaddr *)&m_data[m_index].server,sizeof(m_data[m_index].server)) == SOCKET_ERROR)
{
int i=GetLastError();
return 0;
}

GetResolution();
SetGrids(hWnd);

memset(szMessage,'\0',sizeof(szMessage));
sprintf(szMessage,"WM_COMP;%d;0;0;0;\0",10);
SendCommandM(hWnd,1,szMessage,NULL);

UpdateRegionalScreen(hWnd,m_data[m_index].sClient,TRUE,m_child_wnd);

return m_data[m_index].sClient;
}


其中
if (connect(m_data[m_index].sClient,(struct sockaddr *)&m_data[m_index].server,sizeof(m_data[m_index].server)) == SOCKET_ERROR)
这一句,如果要链接的机子关机了,也就是说是个无效IP,这个地方会一直等下去,直到windows认为连不上了为止,

我要问的就是,能不能在这之前设置一下超时呢?
我想超过5秒就不让他等了,让它运行下面的代码,怎么设置这个时间呢?用什么API?
...全文
782 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
LiSCode 2009-06-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 dux003 的回复:]


注意这一句
fcntl(SocketFd,F_SETFL,O_NONBLOCK|flags);
已经设为非阻塞的了
[/Quote]

他这个例子里面有些变量没定义!!!!!!!!!
lijianli9 2009-06-24
  • 打赏
  • 举报
回复
大致就是先设置非阻塞的,然后connent,然后再用select模型中的select函数控制。
//设置非阻塞方式连接
unsigned long ul = 1;
int ret;
ret = ioctlsocket(m_sock, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
return FALSE;

::connect(m_sock,(sockaddr *)&m_ServerAddr,sizeof(sockaddr_in));
//select 模型,即设置超时
struct timeval timeout ;
fd_set r;

FD_ZERO(&r);
FD_SET(m_sock, &r);
timeout.tv_sec = 2; //连接超时2秒
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if(ret<=0)
{
::closesocket(m_sock);
return false;
}
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(m_sock, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR)
{
::closesocket(m_sock);
return false;
}
return true;
ssm1984119 2009-06-24
  • 打赏
  • 举报
回复
我搞了一种方法:先把socket设置为非阻塞模式,调用connect后立马启动一个线程,不断selet,把超时时间设置在select中,就能起到定义超时的作用;连接完毕后,再把socket设置为阻塞模式。
其中CRawSock::s_nConTimeout就是超时时间,单位秒。

while (pThread->m_bSocketGo)
{
bOver = false;
FD_SET(pThread->m_RawSocket,&ReadFds);
FD_SET(pThread->m_RawSocket,&WriteFds);
if (pThread->m_ConStatus==enumConnecting)
{
time_out.tv_sec = CRawSock::s_nConTimeout;
status = select( 0,&ReadFds,&WriteFds,NULL,&time_out);
switch(status)
{
case SOCKET_ERROR:
bOver = true;
break;
case 0:
pThread->m_ConStatus = enumConFail;
pThread->m_pParentThrd->PostThreadMessage(MNG_OTHER_MSG,
MNG_CONOVER,false);
bOver = true;
break;
default:
if (FD_ISSET(pThread->m_RawSocket,&WriteFds))
{
pThread->m_ConStatus = enumConOK;
ioctlsocket(pThread->m_RawSocket,FIONBIO,&ul);
pThread->m_pParentThrd->PostThreadMessage(MNG_OTHER_MSG,
MNG_CONOVER,true);
}
else
{
bOver = true;
}
break;
}
if (bOver)
{
break;
}
}
else
{
iRcvLen = pThread->Receive(pThread->m_pRcvBuff,SOCK_RCV_MAX_BUFF);
if (iRcvLen==SOCKET_ERROR)
{
pThread->m_ConStatus = enumNotCon;
bRcvdOK = false;
bOver = true;
}
else
{
bRcvdOK = true;
}
if (bOver)
{
break;
}
}
Sleep(0);
}
CodeMasterShiller 2009-06-23
  • 打赏
  • 举报
回复


注意这一句
fcntl(SocketFd,F_SETFL,O_NONBLOCK|flags);
已经设为非阻塞的了
LiSCode 2009-06-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 Conry 的回复:]
lz发帖前没有google一下么?

用非阻塞加select来判断超时

可以看看这个帖子,setsockopt是不行的
http://topic.csdn.net/t/20030805/17/2111839.html

这里有用非阻塞加select来判断超时的例子
http://blog.csdn.net/wangyifei0822/archive/2008/03/13/2177293.aspx
[/Quote]

你说的这个,第二个链接中的代码,不知你看过没有,
从理论上来说,是connect等待在这了,也就是说,必须在这个函数之前设置超时,
而这段代码是等connect返回后才设置超时,这不是明摆着找茬吗?
LiSCode 2009-06-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 InitialJ 的回复:]
C/C++ codeint nTime;//你想设置的超时时间
int err=setsockopt(m_socket,SOL_SOCKET,SO_SNDTIMEO,(const char *)&nTime,sizeof(nTime));


m_socket是你所使用的socket
[/Quote]

试了试,不管用啊
Conry 2009-06-23
  • 打赏
  • 举报
回复
lz发帖前没有google一下么?

用非阻塞加select来判断超时

可以看看这个帖子,setsockopt是不行的
http://topic.csdn.net/t/20030805/17/2111839.html

这里有用非阻塞加select来判断超时的例子
http://blog.csdn.net/wangyifei0822/archive/2008/03/13/2177293.aspx
InitialJ 2009-06-23
  • 打赏
  • 举报
回复
如果设置成功会返回0
InitialJ 2009-06-23
  • 打赏
  • 举报
回复
int nTime;//你想设置的超时时间
int err=setsockopt(m_socket,SOL_SOCKET,SO_SNDTIMEO,(const char *)&nTime,sizeof(nTime));

m_socket是你所使用的socket
Wenxy1 2009-06-23
  • 打赏
  • 举报
回复
调用 setsockopt()来设置,
你也不查查设置成功了没有,去检查返回值。

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧