为CSocket配置Time-Out功能

为CSocket配置Time-Out功能
    CSocket操作,如Send(),Receive(),Connect()都属阻塞操作,即它们在成功完成或错误发生之前是不会返回的。
    在某些情况下,某项操作可能永远不能成功完成,程序为了等待其完成就得永远循环下去。在程序中为某项操作限定一个成功完成的时间是个好主意。本文就是讨论此问题的。
    一个办法是设计一个计时器,当操作费时过长时就触发。这个办法的关键是怎样处理计时器。虽然操作是"阻塞"的,但仍具处理传回的消息的能力。如果用SetTimer来设置计时器,就可截获WM_TIMER消息,当它产生时就终止操作。涉及到这个过程的主要函数是:Windows API ::SetTimer(),MFC函数CSocket::OnMessagePending()和CSocket:: CancelBlockingCall()。这些功能可包装到你的CSocket类中得以简化。
    类中用到三个重要函数:
    BOOL SetTimeOut(UINT uTimeOut) 它应在CSocket函数调用前被调用。uTimeOut以千分秒为单位。下面的实现只是简单的设置计时器。当设置计时器失败时返回False。参见Windows API中关于SetTimer的说明。
    BOOL KillTimeOut() 此函数应在操作未完成被阻塞时被调用。它删除SetTimeOut所设置的计时器。如果调用KillTimer失败则返回False。参见Windows API中关于KillTimer的说明。
    BOOL OnMessagePending() 它是一个虚拟回调函数,当等待操作完成时被CSocket类调用。它给你机会来处理传回的消息。这次我们用它来检查SetTimeOut所设置的计时器,如果超时(Time-Out),则它调用CancelBlockingCall()。参见MFC文档关于OnMessagePending()和CancelBlockingCall()的说明。注意调用CancelBlockingCall()将使当前操作失败,GetLastError()函数返回WSAEINTR(指出是中断操作)。
    下面就是使用这个类的例子:
   ...
   CTimeOutSocket sockServer;
   CAcceptedSocket sockAccept;

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

   // Note the following sequence:
   //  SetTimeOut
   //  <operation which might block>
   //  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?
     // 
   }
   ...

    下面是示例代码:

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

   // 
   // IMPLEMENTATION FILE
   // 
   BOOL CTimeOutSocket::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 CTimeOutSocket::SetTimeOut(UINT uTimeOut)
   {
     m_nTimerID = SetTimer(NULL,0,uTimeOut,NULL);
     return m_nTimerID;
   }

   BOOL CTimeOutSocket::KillTimeOut()
   {
     return KillTimer(NULL,m_nTimerID);
   }
阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
VC是Visual C++的缩写,Csocket是其所提供的一个网络编程类库。利用VC和Csocket可以实现远程桌面功能。 远程桌面是指通过网络连接到远程计算机,可以在本地显示并操作远程计算机的桌面。实现远程桌面功能的基本过程如下: 1. 创建一个VC项目,并添加Csocket类库。 2. 创建一个服务器端程序和一个客户端程序。服务器端程序负责接受远程控制请求,客户端程序则负责发送控制指令给服务器端。 3. 在服务器端程序中,创建一个Socket对象,并绑定相应的IP地址和端口号。通过调用Socket对象的Listen方法,使其处于监听状态。 4. 在服务器端程序中,通过调用Socket对象的Accept方法,等待客户端的连接请求。当客户端发起连接请求时,Accept方法会返回一个新的Socket对象,表示与客户端的连接。 5. 在服务器端程序中,通过新的Socket对象,可以进行数据的接收和发送操作。通过接收客户端发送的控制指令,服务器端可以根据指令对远程桌面进行操作。 6. 在客户端程序中,创建一个Socket对象,并连接到服务器端的IP地址和端口号。 7. 在客户端程序中,通过Socket对象,发送控制指令给服务器端。根据用户的操作,可以发送鼠标点击、键盘输入等指令。 8. 在客户端程序中,通过Socket对象,接收服务器端发送的远程桌面图像数据。接收到的图像数据可以在本地窗口进行显示。 通过以上步骤,利用VC和Csocket可以实现远程桌面功能。服务器端负责接收远程控制请求并对远程桌面进行操作,客户端负责发送控制指令和接收远程桌面图像数据。这样,用户可以通过本地计算机实现对远程计算机的桌面进行操作,便捷地进行远程工作或管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蝈蝈俊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值