CSocket超时(Time-Out)功能的设置及其局限性

news/2024/7/5 4:44:16

CSocket 是一个同步的socket类,如“接收”(Receive)、“发送”(Send) 和“连接”(Connect) 均是阻塞操作,即要等到操作成功执行完毕或套接字上出现错误后,对这些函数的调用才有返回结果。如果连接不上,只有超时以后才能返回。

在某些情况下,操作可能永远不能成功完成,这将导致程序无限循环等待操作完成。例如错误的域名解释,连接不上的IP地址,这回让用户等待近 40秒钟的时间(可能是默认的超时时间),而且等待期间,程序将会"假死", 如果这种情况频繁出现,软件就无法使用了。

微软MSDN上提供了一种解决方法:通过编程限制完成操作使用的时间。只要超过这个时间,无论是否成功都要返回。

示例代码:

//
   // HEADER FILE
   //
   class TimeOut_CSocket : public CSocket
   {
   public:
     BOOL SetTimeOut(UINT uTimeOut);
     BOOL KillTimeOut();
   protected:
     virtual BOOL OnMessagePending();
   private:
     int m_nTimerID;
   };
   //
   // END OF FILE
   //


   //
   // IMPLEMENTATION FILE
   //
   BOOL TimeOut_CSocket::OnMessagePending()
   {
     MSG msg;
     if(::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE))
     {
       if (msg.wParam == (UINT) m_nTimerID)
       {
         // Remove the message and call CancelBlockingCall.
         ::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE);
         CancelBlockingCall();
         return FALSE;  // No need for idle time processing.
       };
     };

     return CSocket::OnMessagePending();
   }

   BOOL TimeOut_CSocket::SetTimeOut(UINT uTimeOut)
   {
     m_nTimerID = SetTimer(NULL,0,uTimeOut,NULL);
     return m_nTimerID;
   }

   BOOL TimeOut_CSocket::KillTimeOut()
   {
     return KillTimer(NULL,m_nTimerID);
   }

 

 

 

有了这个CSocket的派生类后,就能自由设置 自己的 超时时间了,例如:

...
   TimeOut_CSocket sockServer;
   CAcceptedSocket sockAccept;

   sockServer.Create(777);
   sockServer.Listen();

   // Note the following sequence:
   //  SetTimeOut
   // 
   //  KillTimeOut

   if(!sockServer.SetTimeOut(10000))
   {
     ASSERT(FALSE);
     // Error Handling...for some reason, we could not setup
     // the timer.
   }

   if(!sockServer.Accept(sockAccept))
   {
     int nError = GetLastError();
     if(nError==WSAEINTR)
       AfxMessageBox("No Connections Arrived For 10 Seconds");
      else
        ; // Do other error processing.
   }

   if(!sockServer.KillTimeOut())
   {
     ASSERT(FALSE);
     // Error Handling...for some reason the timer could not
     // be destroyed...perhaps a memory overwrite has changed
     // m_nTimerID?
     //
   }
   ...

这个方法经过测试还是有很大地局限性,当服务器联通时,确实能按照超时时间返回,但如果域名解释有问题或者ip地址连接不上,还是需要等待20s以上的超时时间。

要达到商业化软件的要求,我们推荐还是用专业的socket组件解决网络操作问题, 例如

糖果专业下载组件 就能做到 程序随时可以退出,永不"假死":

 

糖果专业下载组件 支持 多源 多线程下载, 支持各种代理,尤其是 能够穿透 局域网中的 ISA Server代理服务器(需要支持NTLM认证),做到IE能上网,软件就能上网。

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1763529



http://www.niftyadmin.cn/n/3659434.html

相关文章

前后端分离开发概念

前端后端需要会写html,css,js,jqcontroller,service,mapper主要作用数据显示返回数据或者操作数据接口ajax操作 开发接口,不是interface 而是开发controller,service,mapper过程 开发文档

SOCkET编程 难点及要点

刚从一个网络项目上脱出身来, 感叹Widnows软件开发,有两个难点,一个是窗口系统界面设计,一个就是Socket编程。此次作的是一个多源多线程下载项目 - 糖果专业下载组件,是一个ActiveX控件。这个项目的起因源于 糖果音乐播…

SOCKET代理实现方法

代理服务器的工作机制很象我们生活中常常提及的代理商,假设你的机器为A机,你想获得的数据由B机提供,代理服务器为C机,那么具体的连接过程是这样的。 首先,A机需要B机的数据,它与C机建立连接,C机…

软件工程、项目管理类 重点图书——Be Flying工作室翻译作品展示

为了方便各位对Be Flying工作室翻译的软件工程、项目管理类图书有一个全面的了解和方便查找,将这类图书在此集中展示,欢迎关注:1. Antipatterns: Refactoring Software, Architectures, and Projects in Crisis 中文名:反模式&a…

全部翻译作品 (及时更新)

为了方便各位对Be Flying工作室翻译的科技图书有一个总体的了解和方便查找,这里划分为三类分别予以展示(点击相应类别即可进入相应类别图书的详细展示区)注:本文正处于建设当中,暂未完工。A. 程序设计、软件工程、项目…

CLR一书译者(PART III和Part V)对Renart勘误的回应

下面是针对China-pub上Renart之前的“《CLR via C#》中文版民间勘误”做出的回应。首先非常感谢Renart花精力给出那个勘误,相信对原来的译本是一个很好的补充。下面是我这边请张杰良就第三部分(13-17)和第五部分(30-78&#xff09…

技术译者必读——技术图书翻译方法指南

技术图书翻译方法指南——磨刀不误砍柴工开始翻译之前:需要对所译内容所有章都大体看一下,对于有些以前从未涉及过或者比较生疏的内容稍微深入了解一下,这个过程需要用一天左右的时间,这个非常重要,相当于获得了大致的…

Springboot项目学习-项目搭建

目录 创建项目结构 依赖的版本管理 搭建service模块 搭建service-edu模块 创建项目结构 创建父工程 pom类型 管理依赖版本和公共依赖 springboot工程 子模块 一 maven 子子模块一 maven 子子模块一 子模块 二 ....... 加pom类型 <artifactId>…