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包含超時設定和接收函式。