配置CSocket 操作的超時(shí)時(shí)間_第1頁(yè)
配置CSocket 操作的超時(shí)時(shí)間_第2頁(yè)
配置CSocket 操作的超時(shí)時(shí)間_第3頁(yè)
配置CSocket 操作的超時(shí)時(shí)間_第4頁(yè)
配置CSocket 操作的超時(shí)時(shí)間_第5頁(yè)
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

配置Csocket操作的超時(shí)時(shí)間最后修改:2005年8月24日本文的發(fā)布號(hào)曾為CHS138692轉(zhuǎn)載自/weidagang2046/articles/79285.htmlBOOLSetTimeOut(UINTuTimeOut)BOOLKillTimeOut()BOOLOnMessagePending()示例代碼參考概要CSocket操作,如“接收"(Receive)、“發(fā)送”(Send)和“連接"(Connect)均是阻塞操作,即要等到操作成功執(zhí)行完畢或套接字上出現(xiàn)錯(cuò)誤后,對(duì)這些函數(shù)的調(diào)用才有返回結(jié)果。在某些情況下,操作可能永遠(yuǎn)不能成功完成,這將導(dǎo)致程序無(wú)限循環(huán)等待操作完成。一種解決方法是通過(guò)編程限制完成操作使用的時(shí)間。本文將討論這種方法。這種方法是設(shè)置定時(shí),讓它在操作時(shí)間過(guò)長(zhǎng)時(shí)啟動(dòng)。此方法的關(guān)鍵在于處理定時(shí)器的方式。雖然操作是“阻塞的”,但仍然可以處理到達(dá)的消息。如果通過(guò)使用SetTimer設(shè)置定時(shí)器,那么可以查找WM_TIMER消息,并在收到該消息時(shí)終止操作。該過(guò)程中涉及的主要函數(shù)有:WindowsAPI調(diào)用函數(shù):::SetTimerMFC函數(shù):CSocket::OnMessagePendingCSocket::CancelBlockingCall為簡(jiǎn)單起見,可以在Csocket衍生類中封裝該功能。警告:在進(jìn)一步閱讀本文之前,請(qǐng)注意在某些MFC版本中存在錯(cuò)誤,會(huì)在試圖使用定時(shí)器并重疊OnMessagePending時(shí)引起問(wèn)題。這一問(wèn)題將在下面的MicrosoftKnowledgeBase文章中進(jìn)行討論:137632(/kb/137632/EN-US/)錯(cuò)誤:定時(shí)器激活時(shí)未調(diào)用OnMessagePending本文僅適用于VisualC++的1.52、1.52b、2.1和2.2版本。如果使用的是這些VisualC++版本之一,則還需要實(shí)施所提供的變通解決方法。本文最后部分顯示提供這種超時(shí)功能的類的示例代碼。以下內(nèi)容講述由該類實(shí)現(xiàn)的函數(shù)。BOOLSetTimeOut(UINTuTimeOut)調(diào)用此函數(shù)之后緊接著調(diào)用CSocket函數(shù)(如Receive>Send和Accept)。uTimeOut參數(shù)是以毫秒為單位指定的。之后,進(jìn)行定時(shí)器的設(shè)置。如果設(shè)置定時(shí)器失敗,那么函數(shù)返回FALSE。有關(guān)詳細(xì)情況,請(qǐng)參閱SetTimer函數(shù)的WindowsAPI文檔。BOOLKillTimeOut()在完成阻塞操作后,必須調(diào)用此函數(shù)。此函數(shù)刪除用SetTimeOut設(shè)置的定時(shí)器。如果調(diào)用KillTimer失敗,則返回FALSE。有關(guān)詳細(xì)情況,請(qǐng)參閱KillTimer函數(shù)的WindowsAPI文檔。BOOLOnMessagePending()這是一個(gè)虛擬回調(diào)函數(shù),在等待操作完成時(shí)由CSocket類進(jìn)行調(diào)用。此函數(shù)給您提供處理傳入消息的機(jī)會(huì)。此實(shí)施過(guò)程檢查用SetTimeOut調(diào)用函數(shù)設(shè)置的定時(shí)器的WM_TIMER消息。如果收到消息,則調(diào)用CancelBlockingCall函數(shù)。有關(guān)OnMessagePending和CancelBlockingCall函數(shù)詳細(xì)的信息,請(qǐng)參閱MFC文檔。請(qǐng)注意:調(diào)用CancelBlockingCall函數(shù)將導(dǎo)致操作失敗,而且GetLastError函數(shù)返回WSAEINTR(表示操作中斷)。下面是使用該類的一個(gè)例子:■■■CTimeOutSocketsockServer;CAcceptedSocketsockAccept;sockServer.Create(777);sockServer.Listen();//Notethefollowingsequence://SetTimeOut////KillTimeOutif(!sockServer.SetTimeOut(10000)){ASSERT(FALSE);//ErrorHandling...forsomereason,wecouldnotsetup//thetimer.}if(!sockServer.Accept(sockAccept)){intnError=GetLastError();if(nError==WSAEINTR)AfxMessageBox("NoConnectionsArrivedFor10Seconds");else;//Doothererrorprocessing.}if(!sockServer.KillTimeOut()){ASSERT(FALSE);//ErrorHandling...forsomereasonthetimercouldnot//bedestroyed...perhapsamemoryoverwritehaschanged//m_nTimerID?//}...////HEADERFILE//classCTimeOutSocket:publicCSocket{public:BOOLSetTimeOut(UINTuTimeOut);BOOLKillTimeOut();protected:virtualBOOLOnMessagePending();private:intm_nTimerID;};////ENDOFFILE//////IMPLEMENTATIONFILE//BOOLCTimeOutSocket::OnMessagePending(){MSGmsg;if(::PeekMessage(&msg,NULL,WM_TIMER,WM_TIMER,PM_NOREMOVE)){if(msg.wParam==(UINT)m_nTimerID){//RemovethemessageandcallCancelBlockingCall.::PeekMessage(&msg,NULL,WM_TIMER,WM_TIMER,PM_REMOVE);CancelBlockingCall();returnFALSE;//Noneedforidletimeprocessing.};};returnCSocket::OnMessagePending();}BOOLCTimeOutSocket::SetTimeOut(UINTuTimeOut){m_nTimerID=SetTimer(NULL,0,uTimeOut,NULL);returnm_nTimerID;}BOOLCTimeOutSocket::KillTimeOut(){returnKillTimer(NULL,m_nTimerID);}CSOCKET的超時(shí)設(shè)置和UDP發(fā)送接收使用CSoket多次了,但對(duì)于它的block模式的理解并不是很深入。昨天使用csoket的udp多發(fā)測(cè)試(server接到數(shù)據(jù)后,需要通過(guò)某種方式將數(shù)據(jù)發(fā)送到client,使用tcp方式比較可靠,我一直這樣用的,但是比較費(fèi)時(shí),需要逐一發(fā)送),發(fā)現(xiàn)了問(wèn)題:1)create(),sendto(),receivefrom()....2)其中,發(fā)送方一直定時(shí)發(fā)送數(shù)據(jù)無(wú)問(wèn)題;3)而接收方,通過(guò)一個(gè)單獨(dú)的接收線程實(shí)現(xiàn)(注意:csocket不能跨線程使用!主線程中socketcreate()后,detach()并將sock作為Ipvoid傳入接收線程)。代碼如下://處理接收數(shù)據(jù)UINTCSockSvr::DealSvrRevData(LPVOIDIParam){DWORDdwError;TCHARcBuff[1000];CStringsIP;UINTuPort;for(;!pDlg->m_bExit;){::memset(cBuff,0,sizeof(cBuff));//如果沒有接到數(shù)據(jù),一直等待。。。。//阻塞模式的弊端:::在退出時(shí)候,通過(guò)CancelBlockingCallintiRst=SockSvr.ReceiveFrom(cBuff,sizeof(cBuff),sIP,uPort,0);if(iRst!=SOCKET_ERROR){CStringsTemp=cBuff;TRACE1(_T("\r\nRevData:%s\r\n"),sTemp);}else{dwError=GetLastError();TRACE1(_T("\r\nRevDataErrorcode:%d\r\n"),dwError);}::Sleep(200);}return0;}問(wèn)題:如果發(fā)送方?jīng)]有數(shù)據(jù),SockSvr.ReceiveFrom()會(huì)一致處于等待狀態(tài),導(dǎo)致整個(gè)處理接收線程的停止,如果用戶需要退由結(jié)束程序,無(wú)法正確釋放資源(無(wú)法關(guān)閉在線程函數(shù)重打開的socket--不能跨線程操作socket,無(wú)法關(guān)閉線程),造成系統(tǒng)memoryleak...針對(duì)這種問(wèn)題,微軟的解決辦法是:/default.aspx?scid=kb;zh-cn;138692,經(jīng)過(guò)測(cè)試,在socket進(jìn)行connect()的時(shí)候不好用。后來(lái),結(jié)合微軟的辦法,我通過(guò)自定義的定時(shí)器,實(shí)現(xiàn)了block超時(shí)間后自動(dòng)退出的功能〉#if!defined(AFX_TIMEOUTSOCK_H_19897A81_4EAF_4005_91FD_DC3047725139_INCLUDED_)#defineAFX_TIMEOUTSOCK_H_19897A81_4EAF_4005_91FD_DC3047725139_INCLUDED_#if_MSC_VER>1000#pragmaonce#endif//_MSC_VER>1000//TimeOutSock.h:headerfile///*CSocket操作,如接收(Receive)、發(fā)送(Send)和連接(Connect)均是阻塞操作,即要等到操作成功執(zhí)行完畢或套接字上出現(xiàn)錯(cuò)誤后,對(duì)這些函數(shù)的調(diào)用才有返回結(jié)果。某些情況下,操作可能永遠(yuǎn)不能成功完成,這將導(dǎo)致程序無(wú)限循環(huán)等待操作完成。一種解決方法是通過(guò)編程限制完成操作使用的時(shí)間。本文將討論這種方法。*////////////////////////////////////////////////////////////////////////////////CTimeOutSockcommandtargetclassCTimeOutSock:publicCSocket{//Attributespublic://Operationspublic:CTimeOutSock();virtual~CTimeOutSock();//Overridespublic://ClassWizardgeneratedvirtualfunctionoverrides//{{AFX_VIRTUAL(CTimeOutSock)public:virtualBOOLOnMessagePending();//}}AFX_VIRTUAL//Generatedmessagemapfunctions//{{AFX_MSG(CTimeOutSock)//NOTE-theClassWizardwilladdandremovememberfunctionshere.//}}AFX_MSG/*〃定時(shí)器設(shè)置block超時(shí)不是很好用?!煨l(wèi)話2006.4.19CSocket操作,如接收(Receive)、發(fā)送(Send)和連接(Connect)均是阻塞操作,即要等到操作成功執(zhí)行完畢或套接字上出現(xiàn)錯(cuò)誤后,對(duì)這些函數(shù)的調(diào)用才有返回結(jié)果。某些情況下,操作可能永遠(yuǎn)不能成功完成,這將導(dǎo)致程序無(wú)限循環(huán)等待操作完成。一種解決方法是通過(guò)編程限制完成操作使用的時(shí)間。本文將討論這種方法。*///自己計(jì)算時(shí)間的辦法OKpublic:BOOLSetTimeOut(UINTuTimeOut=1000);BOOLKillTimeOut();private:LONGLONGm_llDtStart;UINTm_uTimeOut;///////////////////////////////////////////////////////////////////////////////}//MicrosoftVisualC++willinsertadditionaldeclarationsimmediatelybeforethepreviousline.#endif//!defined(AFX_TIMEOUTSOCK_H_19897A81_4EAF_4005_91FD_DC3047725139_INCLUDED_)//TimeOutSock.cpp:implementationfile//#include"stdafx.h"#include"NetBroad.h"#include"TimeOutSock.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=_FILE_;#endif///////////////////////////////////////////////////////////////////////////////CTimeOutSockCTimeOutSock::CTimeOutSock(){}CTimeOutSock::~CTimeOutSock()//Donoteditthefollowinglines,whichareneededbyClassWizard.#if0BEGIN_MESSAGE_MAP(CTimeOutSock,CSocket)//}AFX_MSG_MAPEND_MESSAGE_MAP()#endif//0///////////////////////////////////////////////////////////////////////////////CTimeOutSockmemberfunctions〃設(shè)置超時(shí)BOOLCTimeOutSock::SetTimeOut(UINTuTimeOut){//getstartcntLARGE_INTEGERllCnt;::QueryPerformanceCounter(&llCnt);m_llDtStart=llCnt.QuadPart;m_uTimeOut=uTimeOut;returnTRUE;}//刪除超時(shí)參數(shù)BOOLCTimeOutSock::KillTimeOut(){m_llDtStart=0;//表明取消計(jì)時(shí)returnTRUE;}〃檢查是否超時(shí)間BOOLCTimeOutSock::OnMessagePending(){//TODO:Addyourspecializedcodehereand/orcallthebaseclass/*MSGmsg;if(::PeekMessage(&msg,NULL,WM_TIMER,WM_TIMER,PM_NOREMOVE)){if(msg.wParam==(UINT)m_nTimerID){//Removeth

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論