關於CSocket類的Receive超時的問題

2021-04-16 07:51:49 字數 2655 閱讀 1067

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

為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類的Receive超時的問題

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

CSocket類的使用

重點介紹乙個mfc中csocket類的使用 使用csocket類建立套接字物件是通過該類的建構函式建立的。其原型如下 1 csocket csocket 例如,使用者建立csocket類物件,如下 1 csocket sock 如果使用者需要建立套接字物件指標,則應該使用關鍵字new進行建立。如下 ...

CSocket類網路程式設計 MFC

visual c 的mfc提供了csocket類用來實現網路通訊。下面介紹vc 在windows 95中實現socket的 csocket 類相關成員函式 這些成員函式實際上是從casyncsocket 類繼承來的 的使用。1 bool create uint nsocketport 0,int n...