緗戠粶寮曟搸鏁翠綋緇撴瀯錛?br />
SocketItem緇嗚妭錛?br />
鍏堟潵鐪嬪嚑涓簳灞傜粨鏋勶細
//閲嶅彔緇撴瀯綾?/span>
class COverLapped
{
//鍙橀噺瀹氫箟
public:
WSABUF m_WSABuffer; //鏁版嵁鎸囬拡
OVERLAPPED m_OverLapped; //閲嶅彔緇撴瀯
const enOperationType m_OperationType; //鎿嶄綔綾誨瀷
//鍑芥暟瀹氫箟
public:
//鏋勯犲嚱鏁?/span>
COverLapped(enOperationType OperationType);
//鏋愭瀯鍑芥暟
virtual ~COverLapped();
//淇℃伅鍑芥暟
public:
//鑾峰彇綾誨瀷
enOperationType GetOperationType() { return m_OperationType; }
};
//鎺ユ敹閲嶅彔緇撴瀯
class COverLappedSend : public COverLapped
{
//鏁版嵁鍙橀噺
public:
BYTE m_cbBuffer[SOCKET_BUFFER]; //鏁版嵁緙撳啿
//鍑芥暟瀹氫箟
public:
//鏋勯犲嚱鏁?/span>
COverLappedSend();
//鏋愭瀯鍑芥暟
virtual ~COverLappedSend();
};
//閲嶅彔緇撴瀯妯℃澘
template <enOperationType OperationType> class CATLOverLapped : public COverLapped
{
//鍑芥暟瀹氫箟
public:
//鏋勯犲嚱鏁?/span>
CATLOverLapped() : COverLapped(OperationType) {}
//鏋愭瀯鍑芥暟
virtual ~CATLOverLapped() {}
};
鍏堝涔犱笅鍩虹錛學indows涓嬬殑緗戠粶妯″瀷鏈夊緢澶氱錛岃繖閲屽彧鎷垮嚭涓夌鏉ヨ錛?br />EventSelect錛氬熀浜庝俊鍙鋒満鍒訛紝浠ocket涓哄崟浣嶇粦瀹氫俊鍙烽噺錛屽綋socket涓婃湁鎸囧畾鐨勪簨浠跺彂鐢熸椂嬋鍙戜俊鍙鳳紝鐒跺悗鏌ヨ浜嬩歡澶勭悊浜嬩歡閲嶈浜嬩歡錛岀戶緇湪淇″彿閲忎笂絳夊緟銆傚叾瀹炰篃鏄湪浼厠鍒﹕elect妯″瀷涓婄殑鎹笉鎹㈣嵂鐨勫姞寮恒?br />OverLapped錛氬垎涓ょ宸ヤ綔妯″紡瀹屾垚鍥炶皟錛屽拰瀹屾垚浜嬩歡銆傞噸鍙營O鐩戣姣忔鎿嶄綔錛屾瘡嬈O閮界粦瀹氫竴涓噸鍙犲璞★紝褰撴搷浣滃畬鎴愪互鍚庢縺鍙戜俊鍙鋒垨鑰呰皟鐢ㄥ洖璋冦?br />IOCP錛氬拰overlapped綾諱技錛屼笉榪囩粨鏋滅粡榪囦簡Windows鐨勯澶勭悊浠ラ槦鍒楃殑褰㈠紡鎸傚湪瀹屾垚绔彛涓?br />
鏍規嵁涓婇潰鐨勫涔狅紝鍙互寰楀嚭涓涓粨璁猴紝IOCP鐜涓瘡涓嬈O鎿嶄綔閮介渶瑕佷竴涓噸鍙犵粨鏋勶紝閭d箞涓涓狢ServerSocketItem鑷沖皯闇瑕佸浜涜繖浜涗笢涓滐細
浠栬鎺ュ彈鏁版嵁錛屾墍浠ュ繀欏繪湁涓涓帴鍙楁暟鎹殑 OverLapped
瀹冭鍙戦佹暟鎹紝璇翠互蹇呴』鏈変竴涓彂閫佹暟鎹殑 OverLapped
netFox瀵筄verLapped鍋氫簡浣跨敤浜嗙被浼兼睜鐨勭殑綆$悊鎵嬫錛屼粬鐨凷end閮芥槸涓嶇瓑寰呬笂涓嬈″畬鎴愬氨鐩存帴鎶曢掍笅涓涓姹備簡錛岋紝錛岃繖鏄緢鎿嶈泲鐨勫仛娉曪紝錛岋紝
鐒跺悗緇х畫澶嶄範涓嬪熀紜錛?br />鍦‥ventSelect妯″瀷涓幏澶勭悊浠剁被鍨嬫祦紼嬫槸榪欐牱錛?br />event鍙椾俊錛屼嬌鐢?:WSAEnumNetworkEvents鏌ヨ鍜岃繖涓猠vent鍏寵仈鐨剆ocket鍙戠敓鐨勪簨浠訛紝鏍規嵁鏌ヨ鍒扮殑浜嬩歡綾誨瀷鍘誨鐞嗕簨浠?br />鍦ㄤ互姣忎竴嬈O涓烘煡璇㈠璞¢噸鍙營O銆両OCP妯″瀷涓槸榪欐牱錛?br />浣跨敤GetOverlappedResult 鎴栬?GetQueuedCompletionStatus鐒跺悗鏍規嵁閲嶅彔緇撴瀯鍘繪煡璇㈡姇閫掔殑鏄粈涔堢被鍨嬬殑鎿嶄綔錛岀劧鍚庢壘鍒板叧鑱旂殑socket鍘繪搷浣滐紝錛岋紝
榪欐牱蹇呯劧瑕佺粰OverLapped鍋氫釜鎵╁睍錛屾彁渚涗竴縐嶉氳繃OverLapped鏌ヨ鎿嶄綔綾誨瀷鍜宻ocket鐨勮兘鍔涖?br />閫氳繃鍒嗘瀽浠g爜錛宯etFox鍏寵仈socket鏄氳繃鍦ㄥ垱寤哄畬鎴愮鍙g殑鏃跺欑粦瀹歋ocketItem瀵硅薄鎸囬拡瀹屾垚鐨勶紝鎿嶄綔綾誨瀷鏄氳繃瀵筄verLapped緇撴瀯鍔犲己瀹屾垚鐨勩?br />閫氳繃GetQueuedCompletionStatus鑾峰彇鍒板畬鎴怬verLapped浠ュ悗浣跨敤涓涓畯錛?br />錛堣繖鏄疌OverLapped綾誨瀷錛?nbsp; pSocketLapped=CONTAINING_RECORD(pOverLapped,COverLapped,m_OverLapped);
鏉ヨ幏鍙栧寘瑁呭悗鐨凮verLapped錛岀劧鍚庤幏鍙栨搷浣滅被鍨嬶紝鐒跺悗鎵ц鍏蜂綋鎿嶄綔銆?br />鍏跺疄瀹忕殑灞曞紑濡備笅錛?br />錛圕OverLapped*錛?(BYTE*)pOverLapped - (COverLapped*)(0)->m_OverLapped);
pOverLapped鏄幏鍙栧埌鐨勬煇涓狢OverLapped涓殑鎴愬憳鍙橀噺錛?COverLapped*)(0)->m_OverLapped鏄埌鍦–OverLapped涓殑鍋忕Щ錛?(BYTE*)pOverLapped - (COverLapped*)(0)->m_OverLapped) 灝辨槸鏍規嵁pOverLapped鎺ㄧ畻鍑烘潵鐨勫寘鍚湴鍧涓簆OverLapped浣滀負鎴愬憳鍙橀噺m_OverLapped鐨凜OverLapped瀵硅薄鐨勫湴鍧銆?br />鐒跺悗灝卞垎鍒皟鐢細
//鍙戦佸畬鎴愬嚱鏁?br />bool CServerSocketItem::OnSendCompleted(COverLappedSend * pOverLappedSend, DWORD dwThancferred);
//鎺ユ敹瀹屾垚鍑芥暟
bool CServerSocketItem::OnRecvCompleted(COverLappedRecv * pOverLappedRecv, DWORD dwThancferred);
涓烘瘺瑕佸尯鍒哠end OverLapped 鍜?Recv OverLapped鍛紝錛岋紝
搴斾負鎶曢掍竴嬈end涓嶄竴瀹氭槸鐬棿瀹屾垚鐨勶紝鍦ㄥ鐞嗙殑榪囩▼涓瓨鍌ㄦ暟鎹殑鍐呭瓨搴旇鏄攣瀹氱殑錛屼篃灝辨槸涓嶅厑璁鎬慨鏀圭殑錛岋紝錛屾墍浠verLapped搴旇鑷繁綆$悊鍐呭瓨銆?br />鑰宺ecv搴旇涔熸槸闇瑕佹湁涓鐗囧唴瀛樼洿鎺ユ帴鍙楁暟鎹殑錛屽緢濂囨猲etFox娌℃湁鎻愪緵錛岋紝錛?br />
recv灞呯劧鏄湪鎶曢掓帴鍙楄姹傜殑鏃跺欑粰浜嗕竴涓┖鐨刡uffer錛岀劧鍚庡湪瀹屾垚鍥炶皟涓嚜宸卞啀嬈¤皟鐢╮ecv鏂規硶鎺ュ彈鏁版嵁銆?br />鎺ュ彈鏈夊叧鐨勬垚鍛樺彉閲忓涓嬶細
//鐘舵佸彉閲?/span>
protected:
bool m_bNotify; //閫氱煡鏍囧織
bool m_bRecvIng; //鎺ユ敹鏍囧織
bool m_bCloseIng; //鍏抽棴鏍囧織
bool m_bAllowBatch; //鎺ュ彈緹ゅ彂
WORD m_wRecvSize; //鎺ユ敹闀垮害
BYTE m_cbRecvBuf[SOCKET_BUFFER*5]; //鎺ユ敹緙撳啿
int iRetCode=recv(m_hSocket,(char *)m_cbRecvBuf+m_wRecvSize,sizeof(m_cbRecvBuf)-m_wRecvSize,0);
闅鵑亾榪欎箞锠㈢殑鍋氭硶鍙槸涓轟簡韜插紑鍒嗗寘綆楁硶錛?br />鍏蜂綋鐨勭湅鐪嬫帴鍙椾唬鐮侊細
//鎺ユ敹瀹屾垚鍑芥暟
bool CServerSocketItem::OnRecvCompleted(COverLappedRecv * pOverLappedRecv, DWORD dwThancferred)
{
//鏁堥獙鏁版嵁
ASSERT(m_bRecvIng==true);
//璁劇疆鍙橀噺
m_bRecvIng=false;
m_dwRecvTickCount=GetTickCount();
//鍒ゆ柇鍏抽棴
if (m_hSocket==INVALID_SOCKET)
{
CloseSocket(m_wRountID);
return true;
}
//鎺ユ敹鏁版嵁
int iRetCode=recv(m_hSocket,(char *)m_cbRecvBuf+m_wRecvSize,sizeof(m_cbRecvBuf)-m_wRecvSize,0);
if (iRetCode<=0)
{
CloseSocket(m_wRountID);
return true;
}
//鎺ユ敹瀹屾垚
m_wRecvSize+=iRetCode;
BYTE cbBuffer[SOCKET_BUFFER];
CMD_Head * pHead=(CMD_Head *)m_cbRecvBuf;
//澶勭悊鏁版嵁
try
{
while (m_wRecvSize>=sizeof(CMD_Head))
{
//鏁堥獙鏁版嵁
WORD wPacketSize=pHead->CmdInfo.wDataSize;
if (wPacketSize>SOCKET_BUFFER) throw TEXT("鏁版嵁鍖呰秴闀?/span>");
if (wPacketSize<sizeof(CMD_Head)) throw TEXT("鏁版嵁鍖呴潪娉?/span>");
if (pHead->CmdInfo.cbMessageVer!=SOCKET_VER) throw TEXT("鏁版嵁鍖呯増鏈敊璇?/span>");
if (m_wRecvSize<wPacketSize) break;
//鎻愬彇鏁版嵁
CopyMemory(cbBuffer,m_cbRecvBuf,wPacketSize);
WORD wRealySize=CrevasseBuffer(cbBuffer,wPacketSize);
ASSERT(wRealySize>=sizeof(CMD_Head));
m_dwRecvPacketCount++;
//瑙i噴鏁版嵁
WORD wDataSize=wRealySize-sizeof(CMD_Head);
void * pDataBuffer=cbBuffer+sizeof(CMD_Head);
CMD_Command Command=((CMD_Head *)cbBuffer)->CommandInfo;
//鍐呮牳鍛戒護
if (Command.wMainCmdID==MDM_KN_COMMAND)
{
switch (Command.wSubCmdID)
{
case SUB_KN_DETECT_SOCKET: //緗戠粶媯嫻?/span>
{
break;
}
default: throw TEXT("闈炴硶鍛戒護鐮?/span>");
}
}
else
{
//娑堟伅澶勭悊
m_pIServerSocketItemSink->OnSocketReadEvent(Command,pDataBuffer,wDataSize,this);
}
//鍒犻櫎緙撳瓨鏁版嵁
m_wRecvSize-=wPacketSize;
MoveMemory(m_cbRecvBuf,m_cbRecvBuf+wPacketSize,m_wRecvSize);
}
}
catch (
)
{
CloseSocket(m_wRountID);
return false;
}
return RecvData();
}
榪欐槸榪樻槸鏈夊垎鍖呯畻娉曠殑錛屾葷殑鏉ヨ鎺ュ彈嫻佺▼濡備笅錛?br />鐩存帴浣跨敤recv鎶婃暟鎹帴鍙楀埌SocketItem鐨勭紦鍐插尯涓紝褰撻暱搴﹀ぇ浜嶤MD_HEAD涔嬪悗錛岃繘鍏ュ鐞嗛樁孌碉紝澶勭悊head鏁版嵁鍚勭鍒ゆ柇錛岀劧鍚庡皢鏁版嵁鎵斿嚭鍘伙紝鍐嶈皟鏁寸紦鍐插尯錛岋紝錛?br />
綆鍗曠殑璇達細
Send瀹屽叏涓嶈冭檻鍚屾闂錛屼笉綆′竴涓姴鐨勭綉闃熷垪鎶曢扴end璇鋒眰錛岋紝錛岃繖杈瑰鐞嗛槦鍒椾篃鏄洿鎺end瀹屼簨錛屽畬鍏ㄤ笉鑰冭檻涓婁竴嬈℃槸鍚end鎴愬姛錛岋紝錛?br />Recv鏇存槸鑾悕鍏跺鐨勪嬌鐢ㄥ畬鎴愮鍙g粫涓鍦堣繕鍥炲埌recv鐩存帴鎺ュ彈浜嗭紝錛岋紝
寰堢嫍琛鐨勫仛娉曪紝錛岋紝
鏇存涓嬫垜鑷繁鐙楄鐨勪笉鐞嗚В錛?br />濡傛灉涓涓湇鍔″櫒鎻愪氦浜嗛潪甯稿鐨勯噸鍙犵殑receive鍦ㄦ瘡涓涓繛鎺ヤ笂錛岄偅涔堥檺鍒朵細闅忕潃榪炴帴鏁扮殑澧為暱鑰屽彉鍖栥傚鏋滀竴涓湇鍔″櫒鑳藉棰勫厛浼拌鍙兘浼氫駭鐢熺殑鏈澶у茍鍙戣繛鎺ユ暟錛屾湇鍔″櫒鍙互鎶曢掍竴涓嬌鐢ㄩ浂緙撳啿鍖虹殑receive鍦ㄦ瘡涓涓繛鎺ヤ笂銆傚洜涓哄綋浣犳彁浜ゆ搷浣滄病鏈夌紦鍐插尯鏃訛紝閭d箞涔熶笉浼氬瓨鍦ㄥ唴瀛樿閿佸畾浜嗐備嬌鐢ㄨ繖縐嶅姙娉曞悗錛屽綋浣犵殑receive鎿嶄綔浜嬩歡瀹屾垚榪斿洖鏃訛紝璇ocket搴曞眰緙撳啿鍖虹殑鏁版嵁浼氬師灝佷笉鍔ㄧ殑榪樺湪鍏朵腑鑰屾病鏈夎璇誨彇鍒皉eceive鎿嶄綔鐨勭紦鍐插尯鏉ャ傛鏃訛紝鏈嶅姟鍣ㄥ彲浠ョ畝鍗曠殑璋冪敤闈為樆濉炲紡鐨剅ecv灝嗗瓨鍦╯ocket緙撳啿鍖轟腑鐨勬暟鎹叏閮ㄨ鍑烘潵錛屼竴鐩村埌recv榪斿洖 WSAEWOULDBLOCK 涓烘銆?榪欑璁捐闈炲父閫傚悎閭d簺鍙互鐗虹壊鏁版嵁鍚炲悙閲忚屾崲鍙栧法澶?騫跺彂榪炴帴鏁扮殑鏈嶅姟鍣ㄣ傚綋鐒訛紝浣犱篃闇瑕佹剰璇嗗埌濡備綍璁╁鎴風鐨勮涓哄敖閲忛伩鍏嶅鏈嶅姟鍣ㄩ犳垚褰卞搷銆傚湪涓婁竴涓緥瀛愪腑錛屽綋涓涓浂緙撳啿鍖虹殑receive鎿嶄綔琚繑鍥炲悗浣?鐢ㄤ竴涓潪闃誨鐨剅ecv鍘昏鍙杝ocket緙撳啿鍖轟腑鐨勬暟鎹紝濡傛灉鏈嶅姟鍣ㄦ鏃跺彲棰勮鍒板皢浼氭湁鐖嗗彂鐨勬暟鎹祦錛岄偅涔堝彲浠ヨ冭檻姝ゆ椂鎶曢掍竴涓垨鑰呭涓猺eceive 鏉ュ彇浠i潪闃誨鐨剅ecv鏉ヨ繘琛屾暟鎹帴鏀躲傦紙榪欐瘮浣犱嬌鐢?涓己鐪佺殑8K緙撳啿鍖烘潵鎺ユ敹瑕佸ソ鐨勫銆傦級
婧愮爜涓彁渚涗簡涓涓畝鍗曞疄鐢ㄧ殑瑙e喅WSAENOBUF閿欒鐨勫姙娉曘傛垜浠墽琛屼簡涓涓浂瀛楄妭緙撳啿鐨勫紓姝SARead(...)(鍙傝 OnZeroByteRead(..))銆傚綋榪欎釜璇鋒眰瀹屾垚錛屾垜浠煡閬撳湪TCP/IP鏍堜腑鏈夋暟鎹紝鐒跺悗鎴戜滑閫氳繃鎵ц鍑犱釜鏈塎AXIMUMPACKAGESIZE緙撳啿鐨勫紓姝SARead(...)鍘昏錛岃В鍐充簡WSAENOBUFS闂銆備絾鏄繖縐嶈В鍐蟲柟娉曢檷浣庝簡鏈嶅姟鍣ㄧ殑鍚炲悙閲忋?/p>
鎬葷粨錛?
瑙e喅鏂規硶涓錛?
鎶曢掍嬌鐢ㄧ┖緙撳啿鍖虹殑 receive鎿嶄綔錛屽綋鎿嶄綔榪斿洖鍚庯紝浣跨敤闈為樆濉炵殑recv鏉ヨ繘琛岀湡瀹炴暟鎹殑璇誨彇銆傚洜姝ゅ湪瀹屾垚绔彛鐨勬瘡涓涓繛鎺ヤ腑闇瑕佷嬌鐢ㄤ竴涓驚鐜殑鎿嶄綔鏉ヤ笉鏂殑鏉ユ彁浜ょ┖緙撳啿鍖虹殑receive鎿嶄綔銆?
瑙e喅鏂規硶浜岋細
鍦ㄦ姇閫掑嚑涓櫘閫氬惈鏈夌紦鍐插尯鐨剅eceive鎿嶄綔鍚庯紝榪涙帴鐫寮濮嬪驚鐜姇閫掍竴涓┖緙撳啿鍖虹殑receive鎿嶄綔銆傝繖鏍蜂繚璇佸畠浠寜鐓ф姇閫掗『搴忎緷嬈¤繑鍥烇紝榪欐牱鎴戜滑灝辨昏兘瀵硅閿佸畾鐨勫唴瀛樿繘琛岃В閿併?
///////////
濡傛灉涓涓湇鍔″櫒鍚屾椂榪炴帴浜嗚澶氬鎴風, 瀵規瘡涓鎴風鍙堣皟鐢ㄤ簡璁稿 WSARecv, 閭d箞澶ч噺鐨勫唴瀛樺皢浼氳閿佸畾鍒伴潪鍒嗛〉鍐呭瓨姹? 閿佸畾榪欎簺鍐呭瓨鏃舵槸鎸夌収欏甸潰杈圭晫鏉ラ攣瀹氱殑, 涔熷氨鏄鍗充嬌浣?WSARecv 鐨勭紦瀛樺ぇ灝忔槸 1 瀛楄妭, 琚攣瀹氱殑鍐呭瓨涔熷皢浼氭槸 4k. 闈炲垎欏靛唴瀛樻睜鏄敱鏁翠釜緋葷粺鍏辯敤鐨? 濡傛灉鐢ㄥ畬鐨勮瘽鏈鍧忕殑鎯呭喌灝辨槸緋葷粺宕╂簝. 涓涓В鍐沖姙娉曟槸, 浣跨敤澶у皬涓?0 鐨勭紦鍐插尯璋冪敤 WSARecv. 絳夊埌璋冪敤鎴愬姛鏃跺啀鎹㈢敤闈為樆濉炵殑 recv 鎺ユ敹鍒版潵鐨勬暟鎹? 鐩村埌瀹冭繑鍥?WSAEWOULDBLOCK 琛ㄦ槑鏁版嵁宸茬粡鍏ㄩ儴璇誨畬. 鍦ㄨ繖涓繃紼嬩腑娌℃湁浠諱綍鍐呭瓨闇瑕佽閿佸畾, 浣嗗潖澶勬槸鏁堢巼紼嶄綆.

]]>