為CSocket配置Time Out功能

2021-04-13 14:09:31 字數 2648 閱讀 5145

不錯,搜到以下內容,很多****。

為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   //  //  killtimeout   if(!sockserver.settimeout(10000))      if(!sockserver.accept(sockaccept))      if(!sockserver.killtimeout())      ...
下面是示例**:

//    // header file   //    class ctimeoutsocket : public csocket   ;   //    // end of file   //    //    // implementation file   //    bool ctimeoutsocket::onmessagepending()   ;     };     return csocket::onmessagepending();   }   bool ctimeoutsocket::settimeout(uint utimeout)      bool ctimeoutsocket::killtimeout()

我按照以上方式建類並完成**。執行測試後發現並沒有實現效果!onmessagepending沒有監測到wm_timer訊息。

然後我對類進行了調整,一來使得封裝更好,二來外部呼叫基本不用做任何變化,三來希望能使onmessagepending能夠起作用。

其實修改很簡單,就是將settimeout和killtimeout都修改為私有函式,並過載csocket基類的receive和send函式,在收發前後啟動和關閉定時器。

class ctimeoutsocket : public csocket

}afx_virtual

// generated message map functions

//}afx_msg

// implementation

protected:

int m_ntimerid;

private:

bool killtimeout();

bool settimeout(int ntimeout);};

bool ctimeoutsocket::onmessagepending() ;};

return csocket::onmessagepending();}

int ctimeoutsocket::receive(void* lpbuf, int nbuflen, int nflags)

int ctimeoutsocket::send(const void* lpbuf, int nbuflen, int nflags)

bool ctimeoutsocket::settimeout(int ntimeout)

bool ctimeoutsocket::killtimeout()

經過修改的**,執行後onmessagepending得到了wm_timer訊息,正確解決了receive的阻塞問題,同時我只需將原來的csocket物件改為ctimeoutsocket物件就可以了,其它**不用變化。 

為CSocket配置Time Out功能

為csocket配置time out功能 csocket操作,如send receive connect 都屬阻塞操作,即它們在成功完成或錯誤發生之前是不會返回的。在某些情況下,某項操作可能永遠不能成功完成,程式為了等待其完成就得永遠迴圈下去。在程式中為某項操作限定乙個成功完成的時間是個好主意。本文...

為CSocket配置Time Out功能

為csocket配置time out功能 csocket操作,如send receive connect 都屬阻塞操作,即它們在成功完成或錯誤發生之前是不會返回的。在某些情況下,某項操作可能永遠不能成功完成,程式為了等待其完成就得永遠迴圈下去。在程式中為某項操作限定乙個成功完成的時間是個好主意。本文...

為CSocket配置Time Out功能

為csocket配置time out功能 csocket操作,如send receive connect 都屬阻塞操作,即它們在成功完成或錯誤發生之前是不會返回的。在某些情況下,某項操作可能永遠不能成功完成,程式為了等待其完成就得永遠迴圈下去。在程式中為某項操作限定乙個成功完成的時間是個好主意。本文...