CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  网络编程

如何设置TCP sokcet连接的超时时间??connect

楼主eastnofail(Char *)2005-06-10 16:21:43 在 VC/MFC / 网络编程 提问

我搜索过csdn以前的页面,在google里面也搜索过了,只有这一种办法,就是这个帖子里面提到的:  
  http://community.csdn.net/Expert/topic/3153/3153187.xml?temp=.0183832  
   
  但是我试下来,如果去连接一个存在的ip地址,那么connect函数返回一个   10035错误,即   无法立即完成一个非阻塞套接字的操作,但是如果去连接一个不存在的地址,那么connect函数一样会阻塞30秒,那么这样一来的话,这种方法就变得毫无意义.  
   
  比如:局域网里面有一台电脑IP为192.168.0.1,用这种办法去连接的话,超时时间是可以设置的  
  但是我去connect   192.168.0.183   这个不存在的IP地址,那么一样会阻塞30秒!  
   
  能解决吗? 问题点数:100、回复次数:11Top

1 楼krh2001(边城浪子)回复于 2005-06-10 16:29:37 得分 10

本来就是这样的,IP地址是否存在,本来就是看它有没有响应.   不能一下子就确定这是一个不存在的IP的所以要多给点时间它.   30秒   并不算很多Top

2 楼aiyue2010(亚伦)回复于 2005-06-10 16:38:39 得分 5

同意楼上  
  发送SYN后就是看对方有没有返回ACKTop

3 楼goodboyws(深夜不眠者(VCMVP))回复于 2005-06-10 16:46:38 得分 3

应该先ping一下,   windows网络编程里有一个介绍怎么做ping的例子Top

4 楼eastnofail(Char *)回复于 2005-06-10 16:49:43 得分 0

用ping是不行的,如果对方安装了防火墙,禁止了ping,但是允许我的程序通讯,那样的话,就会误认为是网络不通Top

5 楼fisker0303(天塌了,地陷了,小花狗不见了.)回复于 2005-06-10 19:10:53 得分 40

krh2001(边城浪子)说的对,楼主应该知道连接一个远程服务器的原理,第一级路由器上如果找不到申请的ip地址,它就要向上一级路由器汇报,...   ...  
  所以,30秒真的并不长。Top

6 楼fisker0303(天塌了,地陷了,小花狗不见了.)回复于 2005-06-10 19:13:46 得分 36

如果真的不想等30秒那么久,并且你确定等n秒后,如果连接不上,就可以宣布连接失败,可不可以这样。  
  在一个线程中连接,并设置定时器,  
  connect   ...   ...;  
  取消定时器;  
   
  定时器触发后,可以通知用户,连接失败,但实际上,connect还在阻塞中。Top

7 楼softrain(曾经的月光,现在的日光)回复于 2005-06-10 19:47:51 得分 1

使用异步事件模型,或者异步窗口模型Top

8 楼krh2001(边城浪子)回复于 2005-06-10 19:53:06 得分 2

如果你确定,真的不需要等这么久,或者用户希望可以随时中上连接过程,那么一般是用   非阻塞模式来做的.   看看我的这段连接代码(节选),可以作为TCP连接的典范:  
   
  bool   CRemoteLink::Connect()  
  {  
  OnDisconnected();       //   如果已经连接,则断开  
   
  if(!m_bUseProxy)  
  {  
   
  m_iConnStatus   =   SS_CONNECTING;     //   正在连接状态  
  GNTRACE   ("开始连接到远程服务器[%s][%ld]...\n",   m_strip.c_str(),   m_port);  
   
  //   建立套接字,   准备连接到服务器  
  m_socket   =   ::socket(AF_INET,   SOCK_STREAM,   0);  
  if   (socket   <   0)   {  
  if(m_pCallBack)  
  m_pCallBack->OnSocketError(SE_CREATE,   MSG_SE_CREATE);  
  return   false;  
  }  
   
   
  //   设为异步操作方式  
  unsigned   long   on   =   1;  
  if   (::ioctlsocket(m_socket,   FIONBIO,   &on)   <   0)   {  
  ::closesocket(m_socket);  
  if(m_pCallBack)  
  m_pCallBack->OnSocketError(SE_CREATE,   MSG_SE_CREATE);  
  return   false;  
  }  
   
  sockaddr_in   addr;  
  memset(&addr,   0,   sizeof(addr));  
  addr.sin_family   =   AF_INET;  
  addr.sin_addr.s_addr   =   inet_addr(m_strip.c_str());  
  addr.sin_port   =   htons(m_port);  
   
  int   rt;  
  rt   =   ::connect(m_socket,   (sockaddr   *)   &addr,   sizeof(addr));  
  if   (rt   ==   0)   {  
  OnConnected();  
  return   true;  
  }  
   
  //   ==================================================================  
  timeval   to;  
   
  //   首先建立连接  
  fd_set   wfds;  
  fd_set   efds;  
  FD_ZERO(&wfds);  
  FD_ZERO(&efds);  
   
  //   test   shutdown   event   each   100ms.  
  to.tv_sec   =   0; //   CONNECT_TIMEOUT;  
  to.tv_usec   =   100000;  
   
  int   it   =   0;  
  while(!m_meShutdown.Wait(0)   &&   !m_meConnStop.Wait(0))  
  {  
  FD_SET(m_socket,   &wfds);  
  FD_SET(m_socket,   &efds);  
  int   n   =   select(m_socket   +   1,   NULL,   &wfds,   &efds,   &to);  
   
  if   (n   >   0)   {  
  if(FD_ISSET(m_socket,   &wfds))  
  {  
  OnConnected();  
  return   true;  
  }  
  else  
  {  
  //int   err   =   ::WSAGetLastError();  
  //const   char*     msg   =   GetLastErrorMessage(err);  
  GNTRACE   ("CRemoteLink::Connect   :   connection   attempt   failed!\n");  
  if(m_pCallBack)  
  m_pCallBack->OnSocketError(SE_CONN,   MSG_SE_CONN);  
  break;  
  }  
  }   else   if   (n   <   0)   {     //   Select   Error  
  int   err   =   ::WSAGetLastError();  
  const   char*     msg   =   GetLastErrorMessage(err);  
  GNTRACE   ("CRemoteLink::Connect   :   Select   Error.[%d]   -   %s\n",   err,   msg);  
  if(m_pCallBack)  
  m_pCallBack->OnSocketError(err,   msg);  
  break;  
  }  
  else  
  {  
  it   +=   100;  
  if(it   >   30000)             //   连接超时   --   (30S)  
  {  
  GNTRACE   ("CRemoteLink::Connect   :   Time   out.\n");  
  if(m_pCallBack)  
  m_pCallBack->OnSocketError(SE_TIMEOUT,   MSG_SE_TIMEOUT);  
  break;  
  }  
  }  
  }  
  if(m_meConnStop.Wait(0))  
  {  
  GNTRACE("连接过程进行时被取消。\n");  
  }  
  }  
  else  
  {  
  //   通过代理服务器连接  
   
                                    ......   (以下太长,   省略)  
   
   
   
   
  Top

9 楼lianglp(寻找黄金分割点)回复于 2005-06-10 22:07:45 得分 2

用异步吧,当连接上后,也就是说connect()成功后会返回fd_connect消息事件,不过你先要设定此事件通知哦。Top

10 楼0011411(爱也许是假的,可是当时的快乐是真的。)回复于 2005-06-10 22:17:58 得分 1

okTop

11 楼horisly(SUN YAT-SEN UNIVERSITY (逸仙先生))回复于 2005-08-20 03:13:52 得分 0

markTop

相关问题

  • 怎么设置connect函数的超时
  • 修改系统connect超时时间
  • 连接超时的技术: connect 数据库问题。
  • 用Winsock编程,怎么设置connect超时?
  • InternetSetOption(hRequest, INTERNET_OPTION_CONNECT_TIMEOUT,....)怎么设置连接超时啊?
  • 请问一个用select设置connect超时时间的问题?
  • 超时问题
  • 超时问题
  • 代理超时
  • 超时错误?

关键词

  • 连接
  • ip
  • 服务器
  • socket
  • 超时
  • gntrace
  • onsocketerror
  • wfds
  • cremotelink
  • efds

得分解答快速导航

  • 帖主:eastnofail
  • krh2001
  • aiyue2010
  • goodboyws
  • fisker0303
  • fisker0303
  • softrain
  • krh2001
  • lianglp
  • 0011411

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo