1. 程式人生 > >MFC CSocket正確設定接收和傳送超時

MFC CSocket正確設定接收和傳送超時

CSocket超時設定經過測試,只有這樣才能有用。

原理:OnMessagePending是CSocket類的訊息處理函式,我們過載這個虛擬函式,就能處理所有的CSokcet訊息,類似PreTranslateMessage函式。

自己由CSocket派生一個類,類名自己定。

class CTimeOutSock : public CSocket
{
// Attributes

public:
     BOOL SetTimeOut(UINT uTimeOut=1000);
     BOOL KillTimeOut();
private:
 LONGLONG m_llDtStart;
  UINT  m_uTimeOut; 


public:

// Operations
public:
 CTimeOutSock();
 virtual ~CTimeOutSock();

// Overrides
public:
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CTimeOutSock)
 public:
 virtual BOOL OnMessagePending();

 //}}AFX_VIRTUAL

 // Generated message map functions
 //{{AFX_MSG(CTimeOutSock)
  // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG

};

//然後是cpp檔案

#include "stdafx.h"
#include "TimeOutSock.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTimeOutSock

CTimeOutSock::CTimeOutSock()
{

}

CTimeOutSock::~CTimeOutSock()


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CTimeOutSock, CSocket)
 //}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0

/////////////////////////////////////////////////////////////////////////////
// CTimeOutSock member functions

//設定超時
BOOL CTimeOutSock::SetTimeOut(UINT uTimeOut)
{   
 //get start cnt
 LARGE_INTEGER llCnt;
 ::QueryPerformanceCounter(&llCnt);
 m_llDtStart=llCnt.QuadPart; 
 m_uTimeOut=uTimeOut;

     return TRUE;
}

//刪除超時引數
BOOL CTimeOutSock::KillTimeOut()
{
 m_llDtStart=0;//表明取消計時
 return TRUE;
}

//檢查是否超時間
BOOL CTimeOutSock::OnMessagePending() 
{
 // TODO: Add your specialized code here and/or call the base class
 if( m_llDtStart )
 {
  LARGE_INTEGER lldtEnd;
  ::QueryPerformanceCounter(&lldtEnd);  
  LARGE_INTEGER llFrq;
  ::QueryPerformanceFrequency(&llFrq);
  double dbDealy=(double)(lldtEnd.QuadPart-m_llDtStart)*1000/llFrq.QuadPart;
  if( dbDealy>m_uTimeOut )
  {
   CancelBlockingCall();
   return FALSE;  // No need for idle time processing.
  }
 }
 
 return CSocket::OnMessagePending();
}

使用方法:在每一次傳送或者接收之前,設定超時時間,接收完成後面關閉超時。

CTimeOutSocket m_socket;//定義一個物件

char buf[255];

m_socket.SetTimeOut(5000);//5s超時
m_socket.Receive(buf,100);
m_socket.KillTimeOut();

如果覺得麻煩,可以再socket類中寫一個函式OnRecevie包含超時設定和接收函式。