锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 2. 瀹屾垚绔彛鍒涘緩鎴愬姛鍚庯紝鍦⊿ocket鍜屽畬鎴愮鍙d箣闂村緩绔嬪叧鑱斻傚啀嬈¤皟鐢–reateIoCompletionPort 娉ㄦ剰錛欳reateIoCompletionPort鍑芥暟鐨勭3涓弬鏁板厑璁稿紑鍙戜漢鍛樹紶鍏ヤ竴涓被鍨嬩負ULONG_PTR 瀹屾垚绔彛鍒涘緩浠ュ強涓嶴ocket鍏寵仈涔嬪悗錛屽氨瑕佸垱寤轟竴涓垨澶氫釜宸ヤ綔綰跨▼鏉ュ鐞嗗畬鎴愰氱煡錛?br>姣忎釜綰跨▼閮藉彲浠ュ驚鐜湴璋冪敤GetQueuedCompletionStatus鍑芥暟錛屾鏌ュ畬鎴愮鍙d笂鐨勯氱煡浜嬩歡銆?br> 鍦ㄤ婦渚嬭鏄庝竴涓吀鍨嬬殑宸ヤ綔綰跨▼涔嬪墠錛屾垜浠厛璁ㄨ涓涓嬮噸鍙營/O鐨勮繃紼嬨傚埌涓涓噸鍙營/O 娉ㄦ剰錛歄VERLAPPED鎴愬憳涓嶄竴瀹氳姹傛槸OVERLAPPELUS鎵╁睍緇撴瀯鐨勪竴涓垚鍛橈紝鍦ㄨ幏寰?br>OVERLAPPED鎸囬拡涔嬪悗錛屽彲浠ョ敤CONTAINING_RECORD瀹忚幏寰楃浉搴旂殑鎵╁睍緇撴瀯鐨勬寚閽堛?/p>
鍏稿瀷鐨刉orker Thread緇撴瀯錛?br> DWORD WINAPI WorkerThread(LPVOID lpParam) 鏈嶅姟鍣ㄧ鏈瑕佺殑鍔熻兘鍚勬妧鏈氨鏄繖浜涳紝涓嬮潰浠嬬粛瀹㈡埛绔?br> 鍒拌繖瀹㈡埛绔殑涓昏妯″潡鍜屾満鍒跺凡鍩烘湰浠嬬粛瀹屻傚笇鏈涘ソ濂戒綋浼氫竴涓嬭繖縐嶅綰跨▼鏂偣緇紶鐨勬柟娉曘?
Win32閲嶅彔I/O(Overloapped I/O)鏈哄埗鍏佽鍙戣搗涓涓搷浣滐紝鐒跺悗鍦ㄦ搷浣滃畬鎴愪箣鍚庢帴鍙?br>鍒頒俊鎭傚浜庨偅縐嶉渶瑕佸緢闀挎椂闂存墠鑳藉畬鎴愮殑鎿嶄綔鏉ヨ錛岄噸鍙營/O鏈哄埗灝ゅ叾鏈夌敤錛屽洜涓哄彂璧?br>閲嶅彔鎿嶄綔鐨勭嚎紼嬪湪閲嶅彔璇鋒眰鍙戝嚭鍚庡氨鍙互鑷敱鍦板仛鍒殑浜嬫儏浜嗐?br> 鍦╓indows NT/2000涓婏紝鎻愪緵鐪熸鍙墿灞曠殑I/O妯″瀷灝辨槸浣跨敤瀹屾垚绔彛錛圕ompletion
Port)鐨勯噸鍙營/O銆?br> ……
鍙互鎶婂畬鎴愮鍙g湅鎴愮郴緇熺淮鎶ょ殑涓涓槦鍒楋紝鎿嶄綔緋葷粺鎶婇噸鍙營/O鎿嶄綔瀹屾垚鐨勪簨浠墮氱煡
鏀懼埌璇ラ槦鍒楅噷錛岀敱浜庢槸鏆撮湶“鎿嶄綔瀹屾垚”鐨勪簨浠墮氱煡錛屾墍浠ュ懡鍚嶄負“瀹屾垚绔彛”錛圕ompletion
Ports)銆備竴涓猄ocket琚垱寤哄悗錛屽彲浠ュ湪浠諱綍鏃跺埢鍜屼竴涓畬鎴愮鍙h仈緋昏搗鏉ャ?br> 涓鑸潵璇達紝涓涓簲鐢ㄧ▼搴忓彲浠ュ垱寤哄涓伐浣滅嚎紼嬫潵澶勭悊瀹屾垚绔彛涓婄殑閫氱煡浜嬩歡銆傚伐浣?br>綰跨▼鐨勬暟閲忎緷璧栦簬紼嬪簭鐨勫叿浣撻渶瑕併備絾鏄湪鐞嗘兂鐨勬儏鍐典笅錛屽簲璇ュ搴斾竴涓狢PU鍒涘緩涓涓嚎
紼嬨傚洜涓哄湪瀹屾垚绔彛鐞嗘兂妯″瀷涓紝姣忎釜綰跨▼閮藉彲浠ヤ粠緋葷粺鑾峰緱涓涓?#8220;鍘熷瓙”鎬х殑鏃墮棿鐗囷紝杞?br>鐣繍琛屽茍媯鏌ュ畬鎴愮鍙o紝綰跨▼鐨勫垏鎹㈡槸棰濆鐨勫紑閿銆傚湪瀹為檯寮鍙戠殑鏃跺欙紝榪樿鑰冭檻榪欎簺綰?br>紼嬫槸鍚︾壍娑夊埌鍏朵粬鍫靛鎿嶄綔鐨勬儏鍐點傚鏋滄煇綰跨▼榪涜鍫靛鎿嶄綔錛岀郴緇熷垯灝嗗叾鎸傝搗錛岃鍒殑
綰跨▼鑾峰緱榪愯鏃墮棿銆傚洜姝わ紝濡傛灉鏈夎繖鏍風殑鎯呭喌錛屽彲浠ュ鍒涘緩鍑犱釜綰跨▼鏉ュ敖閲忓埄鐢ㄦ椂闂淬?br> 搴旂敤瀹屾垚绔彛鍒嗕袱姝ヨ蛋錛?br> 1. 鍒涘緩瀹屾垚绔彛鍙ユ焺錛?br> HANDLE hIocp;
hIocp=CreateIoCompletionPort(
INVALID_HANDLE_VALUE,
NULL,
(ULONG_PTR)0,
0);
if(hIocp==NULL) {
//濡傛灉閿欒
……
}
娉ㄦ剰鍦ㄧ1涓弬鏁?FileHandle)浼犲叆INVALID_FILE_HANDLE錛岀2涓弬鏁?ExistingCompletionPort)
浼犲叆NULL錛岀郴緇熷皢鍒涘緩涓涓柊鐨勫畬鎴愮鍙e彞鏌勶紝娌℃湁浠諱綍I/O鍙ユ焺涓庡叾鍏寵仈銆?
鍑芥暟錛岃繖涓嬈″湪絎?涓弬鏁癋ileHandle浼犲叆鍒涘緩鐨凷ocket鍙ユ焺錛屽弬鏁癊xistingCompletionPort
涓哄凡緇忓垱寤虹殑瀹屾垚绔彛鍙ユ焺銆?br> 浠ヤ笅浠g爜鍒涘緩浜嗕竴涓猄ocket騫舵妸瀹冨拰瀹屾垚绔彛鑱旂郴璧鋒潵銆?br> SOCKET s;
s=Socket(AF_INET,SOCK_STREAM,0);
if(s==INVALID_SOCKET) {
if(CreateIoCompletionPort((HANDLE)s,
hIocp,
(ULONG_PTR)0,
0)==NULL)
{
//濡傛灉鍒涘緩澶辮觸
……
}
}
鍒版涓烘錛孲ocket宸茬粡鎴愬姛鍜屽畬鎴愮鍙g浉鍏寵仈銆傚湪姝ocket榪涜鐨勯噸鍙營/O鎿嶄綔緇撴灉鍧?br>浣跨敤瀹屾垚绔彛鍙戝嚭閫氱煡銆?/p>
鐨勬暟鎹垚鍛橈紝鎴戜滑鎶婂畠縐頒負瀹屾垚閿?Completion Key)錛屾鏁版嵁鎴愬憳鍙互璁捐涓烘寚鍚戝寘鍚玈ocket
淇℃伅鐨勪竴涓粨鏋勪綋鐨勪竴涓寚閽堬紝鐢ㄦ潵鎶婄浉鍏崇殑鐜淇℃伅鍜孲ocket鑱旂郴璧鋒潵錛屾瘡嬈″畬鎴愰氱煡鏉?br>鍒扮殑鍚屾椂錛岃鐜淇℃伅涔熼殢鐫閫氱煡涓璧瘋繑鍥炵粰寮鍙戜漢鍛樸?/p>
琚彂璧鳳紝涓涓狾verlapped緇撴瀯浣撶殑鎸囬拡灝辮浣滀負鍙傛暟浼犻掔粰緋葷粺銆傚綋鎿嶄綔瀹屾垚鏃訛紝
GetQueueCompletionStatus灝卞彲浠ヨ繑鍥炴寚鍚戝悓涓涓狾verlapped緇撴瀯鐨勬寚閽堛備負浜嗚鯨璁ゅ拰瀹氫綅
榪欎釜宸插畬鎴愮殑鎿嶄綔錛屽紑鍙戜漢鍛樻渶濂藉畾涔夎嚜宸辯殑OVERLAPPED緇撴瀯錛屼互鍖呭惈涓浜涜嚜宸卞畾涔夌殑鍏充簬
鎿嶄綔鏈韓鐨勯澶栦俊鎭傛瘮濡傦細
typedef struct _OVERLAPPELUS {
OVERLAPPED ol;
SOCKET s, sclient;
int OpCode;
WSABUF wbuf;
DWORD dwBytes, dwFlags;
} OVERLAPPELUS;
姝ょ粨鏋勭殑絎?涓垚鍛樹負榛樿鐨凮VERLAPPED緇撴瀯錛岀2鍜岀3涓負鏈湴鏈嶅姟Socket鍜屼笌璇?br>鎿嶄綔鐩稿叧鐨勫鎴穝ocket錛岀4涓垚鍛樹負鎿嶄綔綾誨瀷錛屽浜嶴ocket錛岀幇鍦ㄥ畾涔夌殑鏈変互涓?縐嶏細
#define OP_READ 0
#define OP_WRITE 1
#define OP_ACCEPT 2
鐒跺悗榪樻湁搴旂敤紼嬪簭鐨凷ocket緙撳啿鍖猴紝鎿嶄綔鏁版嵁閲忥紝鏍囧織浣嶄互鍙婂叾浠栧紑鍙戜漢鍛樿涓烘湁鐢?br>鐨勪俊鎭?br> 褰撹繘琛岄噸鍙營/O鎿嶄綔錛屾妸OVERLAPPELUS緇撴瀯浣滀負閲嶅彔I/O鐨勫弬鏁發pOverlapp浼犻掞紙濡?br>WSASend錛學ASRecv錛岀瓑鍑芥暟鐨刲pOverlapped鍙傛暟錛岃姹備紶鍏ヤ竴涓狾VERLAPP緇撴瀯鐨勬寚閽堬級銆?br> 褰撴搷浣滃畬鎴愬悗錛孏etQueuedCompletionStatus鍑芥暟榪斿洖涓涓狶POVERLAPPED綾誨瀷鐨勬寚閽堬紝
榪欎釜鎸囬拡鍏跺疄鏄寚鍚戝紑鍙戜漢鍛樺畾涔夌殑鎵╁睍OVERLAPPELUS緇撴瀯錛屽寘鍚潃寮鍙戜漢鍛樻棭鍏堜紶鍏ョ殑
鍏ㄩ儴淇℃伅銆?/p>
{
ULONG_PTR *PerHandleKey;
OVERLAPPED *Overlap;
OVERLAPPELUS *OverlapPlus, *newolp;
DWORD dwBytesXfered;
while(1)
{
ret=GetQueuedCompletionStatus(
hIocp,
&dwBytesXfered,
(PULONG_PTR)&PerHandleKey,
&Overlap,
INFINITE);
if(ret==0)
{
//濡傛灉鎿嶄綔澶辮觸
continue;
}
OverlapPlus=CONTATING_RECORD(Overlap, OVERLAPPELUS, ol);
switch(OverlapPlus->OpCode)
{
case OP_ACCEPT:
CreateIoCompletionPort(
(HANDLE)OverlapPlus->sclient,
hIocp,
(ULONG_PTR)0,
0);
newolp=AllocateOverlappelus();
newolp->s=OverlapPlus->sclient;
newolp->OpCode=OP_READ;
PrepareSendBuffer(&newolp->wbuf);
ret=WSASend(
newolp->s,
&newolp->wbuf,
1,
&newolp->dwBytes,
0,
&newolp.ol,
NULL);
if(ret==SOCKET_ERROR)
{
if(WSAGetLastError()!=WSA_IO_PENDING)
{
//榪涜閿欒澶勭悊
……
}
}
FreeOverlappelus(OverlapPlus);
SetEvent(hAcceptThread);
break;
case OP_READ:
memset(&OverlapPlus->ol,0,sizeof(OVERLAPPED));
ret=WSARecv(
OverlapPlus->s,
&OverlapPlus->wbuf,
1,
&OverlapPlus->dwBytes,
&OverlapPlus->dwFlags,
&OverlapPlus->ol,
NULL);
if(ret==SOCKET_ERROR)
{
if(WSAGetLastError()!=WSA_IO_PENDING)
{
//閿欒澶勭悊
……
}
}
break;
case OP_WRITE:
break;
}/*switch緇撴潫*/
}/*while緇撴潫*/
}/*WorkerThread緇撴潫*/
娉ㄦ剰錛氬鏋淥verlapped鎿嶄綔绔嬪埢澶辮觸錛堟瘮濡傦紝榪斿洖SOCKET_ERROR鎴栧叾浠栭潪
WSA_IO_PENDING鐨勯敊璇級錛屽垯娌℃湁浠諱綍瀹屾垚閫氱煡浜嬩歡浼氳鏀懼埌瀹屾垚绔彛闃熷垪閲屻傚弽涔嬶紝
鍒欎竴瀹氭湁鐩稿簲鐨勯氱煡浜嬩歡琚斁鍒扮鍙i槦鍒椼?/p>

(鏈枃婧愪唬鐮佽繍琛屾晥鏋滃浘)
瀹炵幇鏂規硶錛圴C錛嬶紜錛屽熀浜嶵CP/IP鍗忚錛夊涓嬶細
浠嶉噯鐢ㄦ湇鍔″櫒涓庡鎴鋒ā寮忥紝闇鍒嗗埆瀵瑰叾璁捐涓庣紪紼嬨?br>鏈嶅姟鍣ㄧ杈冪畝鍗曪紝涓昏灝辨槸鍔犲叆寰呬紶鏂囦歡錛岀洃鍚鎴鳳紝鍜屼紶閫佹枃浠躲傝岄偅浜涙柇鐐圭畫浼犵殑鍔熻兘錛屼互鍙婃枃浠剁殑綆$悊閮芥斁鍦ㄥ鎴風涓娿?br>
涓銆佹湇鍔″櫒绔?/strong>
棣栧厛浠嬬粛鏈嶅姟鍣ㄧ錛?br>鏈寮濮嬫垜浠瀹氫箟涓涓畝鍗曠殑鍗忚錛屼篃灝辨槸瀹氫箟涓涓湇鍔″櫒绔笌瀹㈡埛绔惉寰楁噦鐨勮璦銆傝屼負浜嗘妸闂綆鍖栵紝鎴戝氨璁╂湇鍔″櫒鍙鍚噦涓ゅ彞璇濓紝涓灝辨槸瀹㈡埛璇?#8220;鎴戣璇繪枃浠朵俊鎭?#8221;錛屼簩灝辨槸“鎴戝噯澶囧ソ浜嗭紝鍙互浼犳枃浠朵簡”銆?br>鐢變簬瑕佸疄鐜板綰跨▼錛屽繀欏繪妸鍔熻兘鐙珛鍑烘潵錛屼笖鍖呰鎴愮嚎紼嬶紝棣栧厛寤轟竴涓洃鍚嚎紼嬶紝涓昏璐熻矗鎺ュ叆瀹㈡埛錛屽茍鍚姩鍙︿竴涓鎴風嚎紼嬨傛垜鐢╒C++瀹炵幇濡備笅錛?br>DWORD WINAPI listenthread(LPVOID lpparam)
{
//鐢變富鍑芥暟浼犳潵鐨勫鎺ュ瓧
銆銆SOCKET pthis=(SOCKET)lpparam;
//寮濮嬬洃鍚?
int rc=listen(pthis,30);
//濡傛灉閿欏氨鏄劇ず淇℃伅
if(rc<0){
CString aaa;
aaa="listen閿欒\n";
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
aaa.ReleaseBuffer();
return 0;
}
//榪涘叆寰幆錛屽茍鎺ユ敹鍒版潵鐨勫鎺ュ瓧
while(1){
//鏂板緩涓涓鎺ュ瓧錛岀敤浜庡鎴風
SOCKET s1;
s1=accept(pthis,NULL,NULL);
銆 //緇欎富鍑芥暟鍙戞湁浜鴻仈鍏ユ秷鎭?
CString aa;
aa="涓浜鴻仈鍏ワ紒\n";
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aa.GetBuffer(0),1);
aa.ReleaseBuffer();
DWORD dwthread;
//寤虹珛鐢ㄦ埛綰跨▼
::CreateThread(NULL,0,clientthread,(LPVOID)s1,0,&dwthread);
}
return 0;
}
鎺ョ潃鎴戜滑鏉ョ湅鐢ㄦ埛綰跨▼錛?br>鍏堢湅鏂囦歡娑堟伅綾誨畾涔?/strong>錛?br>
struct fileinfo
{
int fileno;//鏂囦歡鍙?
int type;//瀹㈡埛绔兂璇翠粈涔堬紙鍓嶉潰閭d袱鍙ヨ瘽錛岀敤1,2琛ㄧず錛?
long len;//鏂囦歡闀垮害
int seek;//鏂囦歡寮濮嬩綅緗紝鐢ㄤ簬澶氱嚎紼?
char name[100];//鏂囦歡鍚?
};
鐢ㄦ埛綰跨▼鍑芥暟:
DWORD WINAPI clientthread(LPVOID lpparam)
{
//鏂囦歡娑堟伅
fileinfo* fiinfo;
//鎺ユ敹緙撳瓨
char* m_buf;
m_buf=new char[100];
//鐩戝惉鍑芥暟浼犳潵鐨勭敤鎴峰鎺ュ瓧
SOCKET pthis=(SOCKET)lpparam;
//璇諱紶鏉ョ殑淇℃伅
int aa=readn(pthis,m_buf,100);
//濡傛灉鏈夐敊灝辮繑鍥?
if(aa<0){
closesocket (pthis);
return -1;
}
//鎶婁紶鏉ョ殑淇℃伅杞負瀹氫箟鐨勬枃浠朵俊鎭?
fiinfo=(fileinfo*)m_buf;
CString aaa;
//媯楠屽鎴鋒兂璇翠粈涔?
switch(fiinfo->type)
{
//鎴戣璇繪枃浠朵俊鎭?
case 0:
//璇繪枃浠?
aa=sendn(pthis,(char*)zmfile,1080);
//鏈夐敊
if(aa<0){
closesocket (pthis);
return -1;
}
//鍙戞秷鎭粰涓誨嚱鏁?
aaa="鏀跺埌LIST鍛戒護\n";
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
break;
//鎴戝噯澶囧ソ浜嗭紝鍙互浼犳枃浠朵簡
case 2:
//鍙戞枃浠舵秷鎭粰涓誨嚱鏁?
aaa.Format("%s 鏂囦歡琚姹傦紒%s\n",zmfile[fiinfo->fileno].name,nameph[fiinfo->fileno]);
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
//璇繪枃浠訛紝騫朵紶閫?
readfile(pthis,fiinfo->seek,fiinfo->len,fiinfo->fileno);
//鍚笉鎳備綘璇翠粈涔?
default:
aaa="鎺ユ敹鍗忚閿欒錛乗n";
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
break;
}
return 0;
}
璇繪枃浠跺嚱鏁?/strong>
void readfile(SOCKET so,int seek,int len,int fino)
{
//鏂囦歡鍚?
CString myname;
myname.Format("%s",nameph[fino]);
CFile myFile;
//鎵撳紑鏂囦歡
myFile.Open(myname, CFile::modeRead | CFile::typeBinary|CFile::shareDenyNone);
//浼犲埌鎸囧畾浣嶇疆銆
myFile.Seek(seek,CFile::begin);
char m_buf[SIZE];
int len2;
int len1;
len1=len;
//寮濮嬫帴鏀訛紝鐩村埌鍙戝畬鏁翠釜鏂囦歡
while(len1>0){
len2=len>SIZE?SIZE:len;
myFile.Read(m_buf, len2);
int aa=sendn(so,m_buf,len2);
if(aa<0){
closesocket (so);
break;
}
len1=len1-aa;
len=len-aa;
}
myFile.Close();
}
浜屻佸鎴風
瀹㈡埛绔渶閲嶈錛屼篃鏈澶嶆潅錛屽畠璐熻矗綰跨▼鐨勭鐞嗭紝榪涘害鐨勮褰曠瓑宸ヤ綔銆?br>
澶ф嫻佺▼濡備笅錛?br>鍏堣繛鎺ユ湇鍔″櫒錛屾帴鐫鍙戦佸懡浠?錛堢粰鎴戞枃浠朵俊鎭級錛屽叾涓寘鎷枃浠墮暱搴︼紝鍚嶅瓧絳夛紝鐒跺悗鏍規嵁闀垮害鍐沖畾鍒嗗嚑涓嚎紼嬩笅杞斤紝騫跺垵浣垮寲涓嬭澆榪涚▼錛屾帴鐫鍙戦佸懡浠?錛堝彲浠ョ粰鎴戜紶鏂囦歡浜嗭級錛屽茍璁板綍鏂囦歡榪涚▼銆傛渶鍚庯紝鏀跺熬銆?br>榪欏叾涓湁涓涓崄鍒嗛噸瑕佺殑綾伙紝灝辨槸cdownload綾伙紝瀹氫箟濡備笅錛?class cdownload
{
public:
void createthread();//寮綰跨▼
DWORD finish1();//瀹屾垚綰跨▼
int sendlist();//鍙戝懡浠?
downinfo doinfo;//鏂囦歡淇℃伅錛堜笌鏈嶅姟鍣ㄥ畾涔変竴鏍鳳級
int startask(int n);寮濮嬩紶鏂囦歡n
long m_index;
BOOL good[BLACK];
int filerange[100];
CString fname;
CString fnametwo;
UINT threadfunc(long index);//涓嬭澆榪涚▼
int sendrequest(int n);//鍙戞枃浠朵俊鎭?
cdownload(int thno1);
virtual ~cdownload();
};
涓嬮潰鍏堜粙緇峴endrequest(int n)錛屽湪寮濮嬪墠錛屽悜鏈嶅姟鍣ㄥ彂鑾峰緱鏂囦歡娑堟伅鍛戒護錛屼互渚胯瀹㈡埛绔煡閬撴湁鍝簺鏂囦歡鍙紶
int cdownload::sendrequest(int n)
{
//寤哄鎺ュ瓧
sockaddr_in local;
SOCKET m_socket;
int rc=0;
//鍒濅嬌鍖栨湇鍔″櫒鍦板潃
local.sin_family=AF_INET;
local.sin_port=htons(1028);
local.sin_addr.S_un.S_addr=inet_addr(ip);
m_socket=socket(AF_INET,SOCK_STREAM,0);
int ret;
//鑱旀帴鏈嶅姟鍣?
ret=connect(m_socket,(LPSOCKADDR)&local,sizeof(local));
//鏈夐敊鐨勮瘽
if(ret<0){
AfxMessageBox("鑱旀帴閿欒");
closesocket(m_socket);
return -1;
}
//鍒濅嬌鍖栧懡浠?
fileinfo fileinfo1;
fileinfo1.len=n;
fileinfo1.seek=50;
fileinfo1.type=1;
//鍙戦佸懡浠?
int aa=sendn(m_socket,(char*)&fileinfo1,100);
if(aa<0){
closesocket(m_socket);
return -1;
}
//鎺ユ敹鏈嶅姟鍣ㄤ紶鏉ョ殑淇℃伅
aa=readn(m_socket,(char*)&fileinfo1,100);
if(aa<0){
closesocket(m_socket);
return -1;
}
//鍏抽棴
shutdown(m_socket,2);
closesocket(m_socket);
return 1;
}
鏈変簡鏂囦歡娑堟伅鍚庢垜浠氨鍙互涓嬭澆鏂囦歡浜嗐傚湪涓誨嚱鏁頒腑錛岀敤娉曞涓嬶細
//涓嬭澆絎琧lno涓枃浠訛紝騫朵負瀹冨緩涓涓柊cdownload綾?
down[clno]=new cdownload(clno);
//寮濮嬩笅杞斤紝騫跺垵浣垮寲
type=down[clno]->startask(clno);
//寤虹珛鍚勭嚎紼?
createthread(clno);
涓嬮潰浠嬬粛寮濮嬫柟娉?/strong>:
//寮濮嬫柟娉?
int cdownload::startask(int n)
{
//璇誨叆鏂囦歡闀垮害
doinfo.filelen=zmfile[n].length;
//璇誨叆鍚嶅瓧
fname=zmfile[n].name;
CString tmep;
//鍒濅嬌鍖栨枃浠跺悕
tmep.Format("\\temp\\%s",fname);
//緇欎富鍑芥暟鍙戞秷鎭?
CString aaa;
aaa="姝e湪璇誨彇 "+fname+" 淇℃伅錛岄┈涓婂紑濮嬩笅杞姐傘傘俓n";
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
aaa.ReleaseBuffer();
//濡傛灉鏂囦歡闀垮害灝忎簬0灝辮繑鍥?
if(doinfo.filelen<=0) return -1;
//寤轟竴涓互.down緇撳熬鐨勬枃浠惰褰曟枃浠朵俊鎭?
CString m_temp;
m_temp=fname+".down";
doinfo.name=m_temp;
FILE* fp=NULL;
CFile myfile;
//濡傛灉鏄涓嬈′笅杞芥枃浠訛紝鍒濅嬌鍖栧悇璁板綍鏂囦歡
if((fp=fopen(m_temp,"r"))==NULL){
filerange[0]=0;
//鏂囦歡鍒嗗潡
for(int i=0;i<BLACK;i++)
{
if(i>0)
filerange[i*2]=i*(doinfo.filelen/BLACK+1);
filerange[i*2+1]=doinfo.filelen/BLACK+1;
}
filerange[BLACK*2-1]=doinfo.filelen-filerange[BLACK*2-2];
myfile.Open(m_temp,CFile::modeCreate|CFile::modeWrite | CFile::typeBinary);
//鍐欏叆鏂囦歡闀垮害
myfile.Write(&doinfo.filelen,sizeof(int));
myfile.Close();
銆
CString temp;
for(int ii=0;ii<BLACK;ii++){
//鍒濅嬌鍖栧悇榪涚▼璁板綍鏂囦歡淇℃伅錛堜互.downN緇撳熬錛?
temp.Format(".down%d",ii);
m_temp=fname+temp;
myfile.Open(m_temp,CFile::modeCreate|CFile::modeWrite | CFile::typeBinary);
//鍐欏叆鍚勮繘紼嬫枃浠朵俊鎭?
myfile.Write(&filerange[ii*2],sizeof(int));
myfile.Write(&filerange[ii*2+1],sizeof(int));
myfile.Close();
}
((CMainFrame*)::AfxGetMainWnd())->m_work.m_ListCtrl->AddItemtwo(n,2,0,0,0,doinfo.threadno);
}
else{
//濡傛灉鏂囦歡宸插瓨鍦紝璇存槑鏄畫浼狅紝璇諱笂嬈′俊鎭?
CString temp;
銆
m_temp=fname+".down0";
if((fp=fopen(m_temp,"r"))==NULL)
return 1;
else fclose(fp);
int bb;
bb=0;
//璇誨悇榪涚▼璁板綍鐨勪俊鎭?
for(int ii=0;ii<BLACK;ii++)
{
temp.Format(".down%d",ii);
m_temp=fname+temp;
銆
myfile.Open(m_temp,CFile::modeRead | CFile::typeBinary);
myfile.Read(&filerange[ii*2],sizeof(int));
myfile.Read(&filerange[ii*2+1],sizeof(int));
myfile.Close();
bb = bb+filerange[ii*2+1];
CString temp;
}
if(bb==0) return 1;
doinfo.totle=doinfo.filelen-bb;
銆
((CMainFrame*)::AfxGetMainWnd())->m_work.m_ListCtrl->AddItemtwo(n,2,doinfo.totle,1,0,doinfo.threadno);
}
銆 //寤虹珛涓嬭澆緇撴潫榪涚▼timethread錛屼互綆$幇鍚勮繘紼嬬粨鏉熸椂闂淬?
DWORD dwthread;
::CreateThread(NULL,0,timethread,(LPVOID)this,0,&dwthread);
return 0;
}
涓嬮潰浠嬬粛寤虹珛鍚勮繘紼?/strong>鍑芥暟錛屽緢綆鍗曪細
void CMainFrame::createthread(int threadno)
{
DWORD dwthread;
//寤虹珛BLACK涓繘紼?
for(int i=0;i<BLACK;i++)
{
m_thread[threadno][i]= ::CreateThread(NULL,0,downthread,(LPVOID)down[threadno],0,&dwthread);
}
}
downthread榪涚▼鍑芥暟
DWORD WINAPI downthread(LPVOID lpparam)
{
cdownload* pthis=(cdownload*)lpparam;
//榪涚▼寮曠儲錛?
InterlockedIncrement(&pthis->m_index);
//鎵ц涓嬭澆榪涚▼
pthis->threadfunc(pthis->m_index-1);
return 1;
}
涓嬮潰浠嬬粛涓嬭澆榪涚▼鍑芥暟,鏈鏈鏍稿績鐨勪笢瑗夸簡
UINT cdownload::threadfunc(long index)
{
//鍒濅嬌鍖栬仈鎺?
sockaddr_in local;
SOCKET m_socket;
int rc=0;
銆
local.sin_family=AF_INET;
local.sin_port=htons(1028);
local.sin_addr.S_un.S_addr=inet_addr(ip);
m_socket=socket(AF_INET,SOCK_STREAM,0);
int ret;
//璇誨叆緙撳瓨
char* m_buf=new char[SIZE];
int re,len2;
fileinfo fileinfo1;
//鑱旀帴
ret=connect(m_socket,(LPSOCKADDR)&local,sizeof(local));
//璇誨叆鍚勮繘紼嬬殑涓嬭澆淇℃伅
fileinfo1.len=filerange[index*2+1];
fileinfo1.seek=filerange[index*2];
fileinfo1.type=2;
fileinfo1.fileno=doinfo.threadno;
銆
re=fileinfo1.len;
銆
//鎵撳紑鏂囦歡銆
CFile destFile;
FILE* fp=NULL;
//鏄涓嬈′紶鐨勮瘽
if((fp=fopen(fname,"r"))==NULL)
destFile.Open(fname, CFile::modeCreate|CFile::modeWrite | CFile::typeBinary|CFile::shareDenyNone);
else
//濡傛灉鏂囦歡瀛樺湪錛屾槸緇紶
destFile.Open(fname,CFile::modeWrite | CFile::typeBinary|CFile::shareDenyNone);
//鏂囦歡鎸囬拡縐誨埌鎸囧畾浣嶇疆
destFile.Seek(filerange[index*2],CFile::begin);
//鍙戞秷鎭粰鏈嶅姟鍣紝鍙互浼犳枃浠朵簡
sendn(m_socket,(char*)&fileinfo1,100);
CFile myfile;
CString temp;
temp.Format(".down%d",index);
m_temp=fname+temp;
銆 //褰撳悇孌甸暱搴﹁繕涓嶄負0鏃?
while(re>0){
len2=re>SIZE?SIZE:re;
銆
//璇誨悇孌靛唴瀹?
int len1=readn(m_socket,m_buf,len2);
//鏈夐敊鐨勮瘽
if(len1<0){
closesocket(m_socket);
break;
}
銆
//鍐欏叆鏂囦歡
destFile.Write(m_buf, len1);
//鏇存敼璁板綍榪涘害淇℃伅
filerange[index*2+1]-=len1;
filerange[index*2]+=len1;
//縐誨姩璁板綍鏂囦歡鎸囬拡鍒板ご
myfile.Seek(0,CFile::begin);
//鍐欏叆璁板綍榪涘害
myfile.Write(&filerange[index*2],sizeof(int));
myfile.Write(&filerange[index*2+1],sizeof(int));
//鍑忓幓榪欐璇葷殑闀垮害
re=re-len1;
//鍔犳枃浠墮暱搴?
doinfo.totle=doinfo.totle+len1;
};
//榪欏潡涓嬭澆瀹屾垚錛屾敹灝?
銆
myfile.Close();
destFile.Close();
delete [] m_buf;
shutdown(m_socket,2);
銆
銆
if(re<=0) good[index]=TRUE;
return 1;
}
]]>
閫氬父瑕佸紑鍙戠綉緇滃簲鐢ㄧ▼搴忓茍涓嶆槸涓浠惰交鏉劇殑浜嬫儏錛屼笉榪囷紝瀹為檯涓婂彧瑕佹帉鎻″嚑涓叧閿殑鍘熷垯涔熷氨鍙互浜嗏斺斿垱寤哄拰榪炴帴涓涓鎺ュ瓧錛屽皾璇曡繘琛岃繛鎺ワ紝鐒跺悗鏀跺彂鏁版嵁銆傜湡姝i毦鐨勬槸瑕佸啓鍑轟竴涓彲浠ユ帴綰沖皯鍒欎竴涓紝澶氬垯鏁板崈涓繛鎺ョ殑緗戠粶搴旂敤紼嬪簭銆傛湰鏂囧皢璁ㄨ濡備綍閫氳繃Winsock2鍦╓indows NT 鍜?Windows 2000涓婂紑鍙戦珮鎵╁睍鑳藉姏鐨刉insock搴旂敤紼嬪簭銆傛枃绔犱富瑕佺殑鐒︾偣鍦ㄥ鎴鋒満/鏈嶅姟鍣ㄦā鍨嬬殑鏈嶅姟鍣ㄨ繖涓鏂癸紝褰撶劧錛屽叾涓殑璁稿瑕佺偣瀵規ā鍨嬬殑鍙屾柟閮介傜敤銆?
API涓庡搷搴旇妯?/strong>
閫氳繃Win32鐨勯噸鍙營/O鏈哄埗錛屽簲鐢ㄧ▼搴忓彲浠ユ彁璇蜂竴欏笽/O鎿嶄綔錛岄噸鍙犵殑鎿嶄綔璇鋒眰鍦ㄥ悗鍙板畬鎴愶紝鑰屽悓涓鏃墮棿鎻愯鎿嶄綔鐨勭嚎紼嬪幓鍋氬叾浠栫殑浜嬫儏銆傜瓑閲嶅彔鎿嶄綔瀹屾垚鍚庣嚎紼嬫敹鍒版湁鍏崇殑閫氱煡銆傝繖縐嶆満鍒跺閭d簺鑰楁椂鐨勬搷浣滆岃█鐗瑰埆鏈夌敤銆備笉榪囷紝鍍廤indows 3.1涓婄殑WSAAsyncSelect()鍙奤nix涓嬬殑select()閭f牱鐨勫嚱鏁拌櫧鐒舵槗浜庝嬌鐢紝浣嗘槸瀹冧滑涓嶈兘婊¤凍鍝嶅簲瑙勬ā鐨勯渶瑕併傝屽畬鎴愮鍙f満鍒舵槸閽堝鎿嶄綔緋葷粺鍐呴儴榪涜浜嗕紭鍖栵紝鍦╓indows NT 鍜?Windows 2000涓婏紝浣跨敤浜嗗畬鎴愮鍙g殑閲嶅彔I/O鏈哄埗鎵嶈兘澶熺湡姝f墿澶х郴緇熺殑鍝嶅簲瑙勬ā銆?/p>
瀹屾垚绔彛
涓涓畬鎴愮鍙e叾瀹炲氨鏄竴涓氱煡闃熷垪錛岀敱鎿嶄綔緋葷粺鎶婂凡緇忓畬鎴愮殑閲嶅彔I/O璇鋒眰鐨勯氱煡鏀懼叆鍏朵腑銆傚綋鏌愰」I/O鎿嶄綔涓鏃﹀畬鎴愶紝鏌愪釜鍙互瀵硅鎿嶄綔緇撴灉榪涜澶勭悊鐨勫伐浣滆呯嚎紼嬪氨浼氭敹鍒頒竴鍒欓氱煡銆傝屽鎺ュ瓧鍦ㄨ鍒涘緩鍚庯紝鍙互鍦ㄤ換浣曟椂鍊欎笌鏌愪釜瀹屾垚绔彛榪涜鍏寵仈銆?/p>
閫氬父鎯呭喌涓嬶紝鎴戜滑浼氬湪搴旂敤紼嬪簭涓垱寤轟竴瀹氭暟閲忕殑宸ヤ綔鑰呯嚎紼嬫潵澶勭悊榪欎簺閫氱煡銆傜嚎紼嬫暟閲忓彇鍐充簬搴旂敤紼嬪簭鐨勭壒瀹氶渶瑕併傜悊鎯崇殑鎯呭喌鏄紝綰跨▼鏁伴噺絳変簬澶勭悊鍣ㄧ殑鏁伴噺錛屼笉榪囪繖涔熻姹備換浣曠嚎紼嬮兘涓嶅簲璇ユ墽琛岃濡傚悓姝ヨ鍐欍佺瓑寰呬簨浠墮氱煡絳夐樆濉炲瀷鐨勬搷浣滐紝浠ュ厤綰跨▼闃誨銆傛瘡涓嚎紼嬮兘灝嗗垎鍒頒竴瀹氱殑CPU鏃墮棿錛屽湪姝ゆ湡闂磋綰跨▼鍙互榪愯錛岀劧鍚庡彟涓涓嚎紼嬪皢鍒嗗埌涓涓椂闂寸墖騫跺紑濮嬫墽琛屻傚鏋滄煇涓嚎紼嬫墽琛屼簡闃誨鍨嬬殑鎿嶄綔錛屾搷浣滅郴緇熷皢鍓ュず鍏舵湭浣跨敤鐨勫墿浣欐椂闂寸墖騫惰鍏跺畠綰跨▼寮濮嬫墽琛屻備篃灝辨槸璇達紝鍓嶄竴涓嚎紼嬫病鏈夊厖鍒嗕嬌鐢ㄥ叾鏃墮棿鐗囷紝褰撳彂鐢熻繖鏍風殑鎯呭喌鏃訛紝搴旂敤紼嬪簭搴旇鍑嗗鍏跺畠綰跨▼鏉ュ厖鍒嗗埄鐢ㄨ繖浜涙椂闂寸墖銆?/p>
瀹屾垚绔彛鐨勪嬌鐢ㄥ垎涓轟袱姝ャ傞鍏堝垱寤哄畬鎴愮鍙o紝濡備互涓嬩唬鐮佹墍紺猴細
HANDLE hIocp;
hIocp = CreateIoCompletionPort(
INVALID_HANDLE_VALUE,
NULL,
(ULONG_PTR)0,
0);
if (hIocp == NULL) {
// Error
}
瀹屾垚绔彛鍒涘緩鍚庯紝瑕佹妸灝嗕嬌鐢ㄨ瀹屾垚绔彛鐨勫鎺ュ瓧涓庝箣鍏寵仈璧鋒潵銆傛柟娉曟槸鍐嶆璋冪敤CreateIoCompletionPort ()鍑芥暟錛岀涓涓弬鏁癋ileHandle璁句負濂楁帴瀛楃殑鍙ユ焺錛岀浜屼釜鍙傛暟ExistingCompletionPort 璁句負鍒氬垰鍒涘緩鐨勯偅涓畬鎴愮鍙g殑鍙ユ焺銆?br>浠ヤ笅浠g爜鍒涘緩浜嗕竴涓鎺ュ瓧錛屽茍鎶婂畠鍜屽墠闈㈠垱寤虹殑瀹屾垚绔彛鍏寵仈璧鋒潵錛?
SOCKET s;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
// Error
if (CreateIoCompletionPort((HANDLE)s,
hIocp,
(ULONG_PTR)0,
0) == NULL)
{
// Error
}
...
}
鍦ㄥ垱寤轟簡瀹屾垚绔彛銆佸皢涓涓垨澶氫釜濂楁帴瀛椾笌涔嬬浉鍏寵仈涔嬪悗錛屾垜浠氨瑕佸垱寤鴻嫢騫蹭釜綰跨▼鏉ュ鐞嗗畬鎴愰氱煡銆傝繖浜涚嚎紼嬩笉鏂驚鐜皟鐢℅etQueuedCompletionStatus ()鍑芥暟騫惰繑鍥炲畬鎴愰氱煡銆?/p>
涓嬮潰錛屾垜浠厛鏉ョ湅鐪嬪簲鐢ㄧ▼搴忓浣曡窡韙繖浜涢噸鍙犳搷浣溿傚綋搴旂敤紼嬪簭璋冪敤涓涓噸鍙犳搷浣滃嚱鏁版椂錛岃鎶婃寚鍚戜竴涓猳verlapped緇撴瀯鐨勬寚閽堝寘鎷湪鍏跺弬鏁頒腑銆傚綋鎿嶄綔瀹屾垚鍚庯紝鎴戜滑鍙互閫氳繃GetQueuedCompletionStatus()鍑芥暟涓嬁鍥炶繖涓寚閽堛備笉榪囷紝鍗曟槸鏍規嵁榪欎釜鎸囬拡鎵鎸囧悜鐨刼verlapped緇撴瀯錛屽簲鐢ㄧ▼搴忓茍涓嶈兘鍒嗚鯨絀剁珶瀹屾垚鐨勬槸鍝釜鎿嶄綔銆傝瀹炵幇瀵規搷浣滅殑璺熻釜錛屼綘鍙互鑷繁瀹氫箟涓涓狾VERLAPPED緇撴瀯錛屽湪鍏朵腑鍔犲叆鎵闇鐨勮窡韙俊鎭?/p>
鏃犺浣曟椂璋冪敤閲嶅彔鎿嶄綔鍑芥暟鏃訛紝鎬繪槸浼氶氳繃鍏秎pOverlapped鍙傛暟浼犻掍竴涓狾VERLAPPEDPLUS緇撴瀯(渚嬪WSASend銆?WSARecv絳夊嚱鏁?銆傝繖灝卞厑璁鎬綘涓烘瘡涓涓噸鍙犺皟鐢ㄦ搷浣滆緗煇浜涙搷浣滅姸鎬佷俊鎭紝褰撴搷浣滅粨鏉熷悗錛屼綘鍙互閫氳繃GetQueuedCompletionStatus()鍑芥暟鑾峰緱浣犺嚜瀹氫箟緇撴瀯鐨勬寚閽堛傛敞鎰廜VERLAPPED瀛楁涓嶈姹備竴瀹氭槸榪欎釜鎵╁睍鍚庣殑緇撴瀯鐨勭涓涓瓧孌點傚綋寰楀埌浜嗘寚鍚慜VERLAPPED緇撴瀯鐨勬寚閽堜互鍚庯紝鍙互鐢–ONTAINING_RECORD瀹忓彇鍑哄叾涓寚鍚戞墿灞曠粨鏋勭殑鎸囬拡銆?/p>
OVERLAPPED 緇撴瀯鐨勫畾涔夊涓嬶細
typedef struct _OVERLAPPEDPLUS {
OVERLAPPED ol;
SOCKET s, sclient;
int OpCode;
WSABUF wbuf;
DWORD dwBytes, dwFlags;
// 鍏跺畠鏈夌敤鐨勪俊鎭?
} OVERLAPPEDPLUS;
#define OP_READ 0
#define OP_WRITE 1
#define OP_ACCEPT 2
涓嬮潰璁╂垜浠潵鐪嬬湅宸ヤ綔鑰呯嚎紼嬬殑鎯呭喌銆?br>DWORD WINAPI WorkerThread(LPVOID lpParam)
{
ULONG_PTR *PerHandleKey;
OVERLAPPED *Overlap;
OVERLAPPEDPLUS *OverlapPlus,
*newolp;
DWORD dwBytesXfered;
while (1)
{
ret = GetQueuedCompletionStatus(
hIocp,
&dwBytesXfered,
(PULONG_PTR)&PerHandleKey,
&Overlap,
INFINITE);
if (ret == 0)
{
// Operation failed
continue;
}
OverlapPlus = CONTAINING_RECORD(Overlap, OVERLAPPEDPLUS, ol);
switch (OverlapPlus->OpCode)
{
case OP_ACCEPT:
// Client socket is contained in OverlapPlus.sclient
// Add client to completion port
CreateIoCompletionPort(
(HANDLE)OverlapPlus->sclient,
hIocp,
(ULONG_PTR)0,
0);
// Need a new OVERLAPPEDPLUS structure
// for the newly accepted socket. Perhaps
// keep a look aside list of free structures.
newolp = AllocateOverlappedPlus();
if (!newolp)
{
// Error
}
newolp->s = OverlapPlus->sclient;
newolp->OpCode = OP_READ;
// This function prepares the data to be sent
PrepareSendBuffer(&newolp->wbuf);
ret = WSASend(
newolp->s,
&newolp->wbuf,
1,
&newolp->dwBytes,
0,
&newolp.ol,
NULL);
if (ret == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
// Error
}
}
// Put structure in look aside list for later use
FreeOverlappedPlus(OverlapPlus);
// Signal accept thread to issue another AcceptEx
SetEvent(hAcceptThread);
break;
case OP_READ:
// Process the data read
// ...
// Repost the read if necessary, reusing the same
// receive buffer as before
memset(&OverlapPlus->ol, 0, sizeof(OVERLAPPED));
ret = WSARecv(
OverlapPlus->s,
&OverlapPlus->wbuf,
1,
&OverlapPlus->dwBytes,
&OverlapPlus->dwFlags,
&OverlapPlus->ol,
NULL);
if (ret == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
// Error
}
}
break;
case OP_WRITE:
// Process the data sent, etc.
break;
} // switch
} // while
} // WorkerThread
鍏朵腑姣忓彞鏌勯敭(PerHandleKey)鍙橀噺鐨勫唴瀹癸紝鏄湪鎶婂畬鎴愮鍙d笌濂楁帴瀛楄繘琛屽叧鑱旀椂鎵璁劇疆鐨勫畬鎴愰敭鍙傛暟錛汷verlap鍙傛暟榪斿洖鐨勬槸涓涓寚鍚戝彂鍑洪噸鍙犳搷浣滄椂鎵浣跨敤鐨勯偅涓狾VERLAPPEDPLUS緇撴瀯鐨勬寚閽堛?
瑕佽浣忥紝濡傛灉閲嶅彔鎿嶄綔璋冪敤澶辮觸鏃?涔熷氨鏄錛岃繑鍥炲兼槸SOCKET_ERROR錛屽茍涓旈敊璇師鍥犱笉鏄疻SA_IO_PENDING)錛岄偅涔堝畬鎴愮鍙e皢涓嶄細鏀跺埌浠諱綍瀹屾垚閫氱煡銆傚鏋滈噸鍙犳搷浣滆皟鐢ㄦ垚鍔燂紝鎴栬呭彂鐢熷師鍥犳槸WSA_IO_PENDING鐨勯敊璇椂錛屽畬鎴愮鍙e皢鎬繪槸鑳藉鏀跺埌瀹屾垚閫氱煡銆?br>
Windows NT鍜學indows 2000鐨勫鎺ュ瓧鏋舵瀯
瀵逛簬寮鍙戝ぇ鍝嶅簲瑙勬ā鐨刉insock搴旂敤紼嬪簭鑰岃█錛屽Windows NT鍜學indows 2000鐨勫鎺ュ瓧鏋舵瀯鏈夊熀鏈殑浜嗚В鏄緢鏈夊府鍔╃殑銆備笅鍥炬槸Windows 2000涓殑Winsock鏋舵瀯錛?br>
涓庡叾瀹冪被鍨嬫搷浣滅郴緇熶笉鍚岋紝Windows NT鍜學indows 2000鐨勪紶杈撳崗璁病鏈変竴縐嶉鏍煎儚濂楁帴瀛楅偅鏍風殑銆佸彲浠ュ拰搴旂敤紼嬪簭鐩存帴浜よ皥鐨勭晫闈紝鑰屾槸閲囩敤浜嗕竴縐嶆洿涓哄簳灞傜殑API錛屽彨鍋氫紶杈撻┍鍔ㄧ▼搴忕晫闈?Transport Driver Interface,TDI)銆俉insock鐨勬牳蹇冩ā寮忛┍鍔ㄧ▼搴忚礋璐h繛鎺ュ拰緙撳啿鍖虹鐞嗭紝浠ヤ究鍚戝簲鐢ㄧ▼搴忔彁渚涘鎺ュ瓧浠跨湡(鍦ˋFD.SYS鏂囦歡涓疄鐜?錛屽悓鏃惰礋璐d笌搴曞眰浼犺緭椹卞姩紼嬪簭瀵硅瘽銆?/p>
璋佹潵璐熻矗綆$悊緙撳啿鍖猴紵
姝e涓婇潰鎵璇寸殑錛屽簲鐢ㄧ▼搴忛氳繃Winsock鏉ュ拰浼犺緭鍗忚椹卞姩紼嬪簭浜よ皥錛岃孉FD.SYS璐熻矗涓哄簲鐢ㄧ▼搴忚繘琛岀紦鍐插尯綆$悊銆備篃灝辨槸璇達紝褰撳簲鐢ㄧ▼搴忚皟鐢╯end()鎴朩SASend()鍑芥暟鏉ュ彂閫佹暟鎹椂錛孉FD.SYS灝嗘妸鏁版嵁鎷瘋礉榪涘畠鑷繁鐨勫唴閮ㄧ紦鍐插尯(鍙栧喅浜嶴O_SNDBUF璁懼畾鍊?錛岀劧鍚巗end()鎴朩SASend()鍑芥暟绔嬪嵆榪斿洖銆備篃鍙互榪欎箞璇達紝AFD.SYS鍦ㄥ悗鍙拌礋璐f妸鏁版嵁鍙戦佸嚭鍘匯備笉榪囷紝濡傛灉搴旂敤紼嬪簭瑕佹眰鍙戝嚭鐨勬暟鎹秴榪囦簡SO_SNDBUF璁懼畾鐨勭紦鍐插尯澶у皬錛岄偅涔圵SASend()鍑芥暟浼氶樆濉烇紝鐩磋嚦鎵鏈夋暟鎹彂閫佸畬姣曘?/p>
浠庤繙紼嬪鎴風鎺ユ敹鏁版嵁鐨勬儏鍐典篃綾諱技銆傚彧瑕佷笉鐢ㄤ粠搴旂敤紼嬪簭閭i噷鎺ユ敹澶ч噺鐨勬暟鎹紝鑰屼笖娌℃湁瓚呭嚭SO_RCVBUF璁懼畾鐨勫鹼紝AFD.SYS灝嗘妸鏁版嵁鍏堟嫹璐濆埌鍏跺唴閮ㄧ紦鍐插尯涓傚綋搴旂敤紼嬪簭璋冪敤recv()鎴朩SARecv()鍑芥暟鏃訛紝鏁版嵁灝嗕粠鍐呴儴緙撳啿鎷瘋礉鍒板簲鐢ㄧ▼搴忔彁渚涚殑緙撳啿鍖恒?/p>
澶氭暟鎯呭喌涓嬶紝榪欐牱鐨勬灦鏋勮繍琛岃壇濂斤紝鐗瑰埆鍦ㄦ槸搴旂敤紼嬪簭閲囩敤浼犵粺鐨勫鎺ュ瓧涓嬮潪閲嶅彔鐨剆end()鍜宺eceive()妯″紡緙栧啓鐨勬椂鍊欍備笉榪囩▼搴忓憳瑕佸皬蹇冪殑鏄紝灝界鍙互閫氳繃setsockopt()榪欎釜API鏉ユ妸SO_SNDBUF鍜孲O_RCVBUF閫夐」鍊艱鎴?(鍏抽棴鍐呴儴緙撳啿鍖?錛屼絾鏄▼搴忓憳蹇呴』鍗佸垎娓呮鎶夾FD.SYS鐨勫唴閮ㄧ紦鍐插尯鍏蟲帀浼氶犳垚浠涔堝悗鏋滐紝閬垮厤鏀跺彂鏁版嵁鏃舵湁鍏崇殑緙撳啿鍖烘嫹璐濆彲鑳藉紩璧風殑緋葷粺宕╂簝銆?/p>
涓句緥鏉ヨ錛屼竴涓簲鐢ㄧ▼搴忛氳繃璁懼畾SO_SNDBUF涓?鎶婄紦鍐插尯鍏抽棴錛岀劧鍚庡彂鍑轟竴涓樆濉瀞end()璋冪敤銆傚湪榪欐牱鐨勬儏鍐典笅錛岀郴緇熷唴鏍鎬細鎶婂簲鐢ㄧ▼搴忕殑緙撳啿鍖洪攣瀹氾紝鐩村埌鎺ユ敹鏂圭‘璁ゆ敹鍒頒簡鏁翠釜緙撳啿鍖哄悗send()璋冪敤鎵嶈繑鍥炪備技涔庤繖鏄竴縐嶅垽瀹氫綘鐨勬暟鎹槸鍚﹀凡緇忎負瀵規柟鍏ㄩ儴鏀跺埌鐨勭畝媧佺殑鏂規硶錛屽疄闄呬笂鍗村茍闈炲姝ゃ傛兂鎯崇湅錛屽嵆浣胯繙绔疶CP閫氱煡鏁版嵁宸茬粡鏀跺埌錛屽叾瀹炰篃鏍規湰涓嶄唬琛ㄦ暟鎹凡緇忔垚鍔熼佺粰瀹㈡埛绔簲鐢ㄧ▼搴忥紝姣斿瀵規柟鍙兘鍙戠敓璧勬簮涓嶈凍鐨勬儏鍐碉紝瀵艱嚧AFD.SYS涓嶈兘鎶婃暟鎹嫹璐濈粰搴旂敤紼嬪簭銆傚彟涓涓洿瑕佺揣鐨勯棶棰樻槸錛屽湪姣忎釜綰跨▼涓瘡嬈″彧鑳借繘琛屼竴嬈″彂閫佽皟鐢紝鏁堢巼鏋佸叾浣庝笅銆?/p>
鎶奡O_RCVBUF璁句負0錛屽叧闂瑼FD.SYS鐨勬帴鏀剁紦鍐插尯涔熶笉鑳借鎬ц兘寰楀埌鎻愬崌錛岃繖鍙細榪嬌鎺ユ敹鍒扮殑鏁版嵁鍦ㄦ瘮Winsock鏇翠綆鐨勫眰嬈¤繘琛岀紦鍐詫紝褰撲綘鍙戝嚭receive璋冪敤鏃訛紝鍚屾牱瑕佽繘琛岀紦鍐插尯鎷瘋礉錛屽洜姝や綘鏈潵鎯抽伩鍏嶇紦鍐插尯鎷瘋礉鐨勯槾璋嬩笉浼氬緱閫炪?/p>
鐜板湪鎴戜滑搴旇娓呮浜嗭紝鍏抽棴緙撳啿鍖哄浜庡鏁板簲鐢ㄧ▼搴忚岃█騫朵笉鏄粈涔堝ソ涓繪剰銆傚彧瑕佽搴旂敤紼嬪簭娉ㄦ剰闅忔椂鍦ㄦ煇涓繛鎺ヤ笂淇濇寔鍑犱釜WSARecvs閲嶅彔璋冪敤錛岄偅涔堥氬父娌℃湁蹇呰鍏抽棴鎺ユ敹緙撳啿鍖恒傚鏋淎FD.SYS鎬繪槸鏈夌敱搴旂敤紼嬪簭鎻愪緵鐨勭紦鍐插尯鍙敤錛岄偅涔堝畠灝嗘病鏈夊繀瑕佷嬌鐢ㄥ唴閮ㄧ紦鍐插尯銆?/p>
楂樻ц兘鐨勬湇鍔″櫒搴旂敤紼嬪簭鍙互鍏抽棴鍙戦佺紦鍐插尯錛屽悓鏃朵笉浼氭崯澶辨ц兘銆備笉榪囷紝榪欐牱鐨勫簲鐢ㄧ▼搴忓繀欏誨崄鍒嗗皬蹇冿紝淇濊瘉瀹冩繪槸鍙戝嚭澶氫釜閲嶅彔鍙戦佽皟鐢紝鑰屼笉鏄瓑寰呮煇涓噸鍙犲彂閫佺粨鏉熶簡鎵嶅彂鍑轟笅涓涓傚鏋滃簲鐢ㄧ▼搴忔槸鎸変竴涓彂瀹屽啀鍙戜笅涓涓殑欏哄簭鏉ユ搷浣滐紝閭f氮璐規帀涓ゆ鍙戦佷腑闂寸殑絀烘。鏃墮棿錛屾諱箣鏄淇濊瘉浼犺緭椹卞姩紼嬪簭鍦ㄥ彂閫佸畬涓涓紦鍐插尯鍚庯紝绔嬪埢鍙互杞悜鍙︿竴涓紦鍐插尯銆?/p>
璧勬簮鐨勯檺鍒舵潯浠?/strong>
鍦ㄨ璁′換浣曟湇鍔″櫒搴旂敤紼嬪簭鏃訛紝鍏跺己鍋ユф槸涓昏鐨勭洰鏍囥備篃灝辨槸璇達紝
浣犵殑搴旂敤紼嬪簭瑕佽兘澶熷簲瀵逛換浣曠獊鍙戠殑闂錛屼緥濡傚茍鍙戝鎴瘋姹傛暟杈懼埌宄板箋佸彲鐢ㄥ唴瀛樹復鏃跺嚭鐜頒笉瓚熾佷互鍙婂叾瀹冪煭鏃墮棿鐨勭幇璞°傝繖灝辮姹傜▼搴忕殑璁捐鑰呮敞鎰廤indows NT鍜?000緋葷粺涓嬬殑璧勬簮闄愬埗鏉′歡鐨勯棶棰橈紝浠庡鍦板鐞嗙獊鍙戞т簨浠躲?/p>
浣犲彲浠ョ洿鎺ユ帶鍒剁殑銆佹渶鍩烘湰鐨勮祫婧愬氨鏄綉緇滃甫瀹姐傞氬父錛屼嬌鐢ㄧ敤鎴鋒暟鎹姤鍗忚(UDP)鐨勫簲鐢ㄧ▼搴忛兘鍙兘浼氭瘮杈冩敞鎰忓甫瀹芥柟闈㈢殑闄愬埗錛屼互鏈澶ч檺搴﹀湴鍑忓皯鍖呯殑涓㈠け銆傜劧鑰岋紝鍦ㄤ嬌鐢═CP榪炴帴鏃訛紝鏈嶅姟鍣ㄥ繀欏誨崄鍒嗗皬蹇冨湴鎺у埗濂斤紝闃叉緗戠粶甯﹀榪囪澆瓚呰繃涓瀹氱殑鏃墮棿錛屽惁鍒欏皢闇瑕侀噸鍙戝ぇ閲忕殑鍖呮垨閫犳垚澶ч噺榪炴帴涓柇銆傚叧浜庡甫瀹界鐞嗙殑鏂規硶搴旀牴鎹笉鍚岀殑搴旂敤紼嬪簭鑰屽畾錛岃繖瓚呭嚭浜嗘湰鏂囪璁虹殑鑼冨洿銆?/p>
铏氭嫙鍐呭瓨鐨勪嬌鐢ㄤ篃蹇呴』寰堝皬蹇冨湴綆$悊銆傞氳繃璋ㄦ厧鍦扮敵璇峰拰閲婃斁鍐呭瓨錛屾垨鑰呭簲鐢╨ookaside lists(涓縐嶉珮閫熺紦瀛?鎶鏈潵閲嶆柊浣跨敤宸插垎閰嶇殑鍐呭瓨錛屽皢鏈夊姪浜庢帶鍒舵湇鍔″櫒搴旂敤紼嬪簭鐨勫唴瀛樺紑閿(鍘熸枃涓?#8220;璁╂湇鍔″櫒搴旂敤紼嬪簭鐣欎笅鐨勮剼鍗板皬涓鐐?#8221;)錛岄伩鍏嶆搷浣滅郴緇熼綣佸湴灝嗗簲鐢ㄧ▼搴忕敵璇風殑鐗╃悊鍐呭瓨浜ゆ崲鍒拌櫄鎷熷唴瀛樹腑(鍘熸枃涓?#8220;璁╂搷浣滅郴緇熻兘澶熸繪槸鎶婃洿澶氱殑搴旂敤紼嬪簭鍦板潃絀洪棿鏇村鍦頒繚鐣欏湪鍐呭瓨涓?#8221;)銆備綘涔熷彲浠ラ氳繃SetWorkingSetSize()榪欎釜Win32 API璁╂搷浣滅郴緇熷垎閰嶇粰浣犵殑搴旂敤紼嬪簭鏇村鐨勭墿鐞嗗唴瀛樸?/p>
鍦ㄤ嬌鐢╓insock鏃惰繕鍙兘紕板埌鍙﹀涓や釜闈炵洿鎺ョ殑璧勬簮涓嶈凍鎯呭喌銆備竴涓槸琚攣瀹氱殑鍐呭瓨欏甸潰鐨勬瀬闄愩傚鏋滀綘鎶夾FD.SYS鐨勭紦鍐插叧闂紝褰撳簲鐢ㄧ▼搴忔敹鍙戞暟鎹椂錛屽簲鐢ㄧ▼搴忕紦鍐插尯鐨勬墍鏈夐〉闈㈠皢琚攣瀹氬埌鐗╃悊鍐呭瓨涓傝繖鏄洜涓哄唴鏍擱┍鍔ㄧ▼搴忛渶瑕佽闂繖浜涘唴瀛橈紝鍦ㄦ鏈熼棿榪欎簺欏甸潰涓嶈兘浜ゆ崲鍑哄幓銆傚鏋滄搷浣滅郴緇熼渶瑕佺粰鍏跺畠搴旂敤紼嬪簭鍒嗛厤涓浜涘彲鍒嗛〉鐨勭墿鐞嗗唴瀛橈紝鑰屽張娌℃湁瓚沖鐨勫唴瀛樻椂灝變細鍙戠敓闂銆傛垜浠殑鐩爣鏄闃叉鍐欏嚭涓涓梾鎬佺殑銆侀攣瀹氭墍鏈夌墿鐞嗗唴瀛樸佽緋葷粺宕╂簝鐨勭▼搴忋備篃灝辨槸璇達紝浣犵殑紼嬪簭閿佸畾鍐呭瓨鏃訛紝涓嶈瓚呭嚭緋葷粺瑙勫畾鐨勫唴瀛樺垎欏墊瀬闄愩?/p>
鍦╓indows NT鍜?000緋葷粺涓婏紝鎵鏈夊簲鐢ㄧ▼搴忔誨叡鍙互閿佸畾鐨勫唴瀛樺ぇ綰︽槸鐗╃悊鍐呭瓨鐨?/8(涓嶈繃榪欏彧鏄竴涓ぇ姒傜殑浼拌錛屼笉鏄綘璁$畻鍐呭瓨鐨勪緷鎹?銆傚鏋滀綘鐨勫簲鐢ㄧ▼搴忎笉娉ㄦ剰榪欎竴鐐癸紝褰撲綘鐨勫彂鍑哄お澶氱殑閲嶅彔鏀跺彂璋冪敤錛岃屼笖I/O娌℃潵寰楀強瀹屾垚鏃訛紝灝卞彲鑳藉伓灝斿彂鐢烢RROR_INSUFFICIENT_RESOURCES鐨勯敊璇傚湪榪欑鎯呭喌涓嬩綘瑕侀伩鍏嶈繃搴﹂攣瀹氬唴瀛樸傚悓鏃惰娉ㄦ剰錛岀郴緇熶細閿佸畾鍖呭惈浣犵殑緙撳啿鍖烘墍鍦ㄧ殑鏁翠釜鍐呭瓨欏甸潰錛屽洜姝ょ紦鍐插尯闈犺繎欏佃竟鐣屾椂鏄湁浠d環鐨?璇戣呯悊瑙o紝緙撳啿鍖哄鏋滄濂借秴榪囬〉闈㈣竟鐣岋紝閭f曟槸1涓瓧鑺傦紝瓚呭嚭鐨勮繖涓瓧鑺傛墍鍦ㄧ殑欏甸潰涔熶細琚攣瀹?銆?/p>
鍙﹀涓涓檺鍒舵槸浣犵殑紼嬪簭鍙兘浼氶亣鍒扮郴緇熸湭鍒嗛〉姹犺祫婧愪笉瓚崇殑鎯呭喌銆傛墍璋撴湭鍒嗛〉姹犳槸涓鍧楁案榪滀笉琚氦鎹㈠嚭鍘葷殑鍐呭瓨鍖哄煙錛岃繖鍧楀唴瀛樼敤鏉ュ瓨鍌ㄤ竴浜涗緵鍚勭鍐呮牳緇勪歡璁塊棶鐨勬暟鎹紝鍏朵腑鏈夌殑鍐呮牳緇勪歡鏄笉鑳借闂偅浜涜浜ゆ崲鍑哄幓鐨勯〉闈㈢┖闂寸殑銆俉indows NT鍜?000鐨勯┍鍔ㄧ▼搴忚兘澶熶粠榪欎釜鐗瑰畾鐨勬湭鍒嗛〉姹犲垎閰嶅唴瀛樸?/p>
褰撳簲鐢ㄧ▼搴忓垱寤轟竴涓鎺ュ瓧(鎴栬呮槸綾諱技鐨勬墦寮鏌愪釜鏂囦歡)鏃訛紝鍐呮牳浼氫粠鏈垎欏墊睜涓垎閰嶄竴瀹氭暟閲忕殑鍐呭瓨錛岃屼笖鍦ㄧ粦瀹氥佽繛鎺ュ鎺ュ瓧鏃訛紝鍐呮牳鍙堜細浠庢湭鍒嗛〉姹犱腑鍐嶅垎閰嶄竴浜涘唴瀛樸傚綋浣犳敞鎰忚瀵熻繖縐嶈涓烘椂浣犲皢鍙戠幇錛屽鏋滀綘鍙戝嚭鏌愪簺I/O璇鋒眰鏃?渚嬪鏀跺彂鏁版嵁)錛屼綘浼氫粠鏈垎欏墊睜閲屽啀鍒嗛厤澶氫竴浜涘唴瀛?姣斿瑕佽拷韙煇涓緟鍐崇殑I/O鎿嶄綔錛屼綘鍙兘闇瑕佺粰榪欎釜鎿嶄綔娣誨姞涓涓嚜瀹氫箟緇撴瀯錛屽鍓嶆枃鎵鎻愬強鐨?銆傛渶鍚庤繖灝卞彲鑳戒細閫犳垚涓瀹氱殑闂錛屾搷浣滅郴緇熶細闄愬埗鏈垎欏靛唴瀛樼殑鐢ㄩ噺銆?/p>
鍦╓indows NT鍜?000榪欎袱縐嶆搷浣滅郴緇熶笂錛岀粰姣忎釜榪炴帴鍒嗛厤鐨勬湭鍒嗛〉鍐呭瓨鐨勫叿浣撴暟閲忔槸涓嶅悓鐨勶紝鏈潵鐗堟湰鐨刉indows寰堝彲鑳戒篃涓嶅悓銆備負浜嗕嬌搴旂敤紼嬪簭鐨勭敓鍛芥湡鏇撮暱錛屼綘灝變笉搴旇璁$畻瀵規湭鍒嗛〉姹犲唴瀛樼殑鍏蜂綋闇姹傞噺銆?/p>
浣犵殑紼嬪簭蹇呴』闃叉娑堣楀埌鏈垎欏墊睜鐨勬瀬闄愩傚綋緋葷粺涓湭鍒嗛〉姹犲墿浣欑┖闂村お灝忔椂錛屾煇浜涗笌浣犵殑搴旂敤紼嬪簭姣棤鍏崇郴鐨勫唴鏍擱┍鍔ㄥ氨浼氬彂鐤紝鐢氳嚦閫犳垚緋葷粺宕╂簝錛岀壒鍒槸褰撶郴緇熶腑鏈夌涓夋柟璁懼鎴栭┍鍔ㄧ▼搴忔椂錛屾洿瀹規槗鍙戠敓榪欐牱鐨勬儴鍓?鑰屼笖鏃犳硶棰勬祴)銆傚悓鏃朵綘榪樿璁頒綇錛屽悓涓鍙扮數鑴戜笂榪樺彲鑳借繍琛屾湁鍏跺畠鍚屾牱娑堣楁湭鍒嗛〉姹犵殑鍏跺畠搴旂敤紼嬪簭錛屽洜姝ゅ湪璁捐浣犵殑搴旂敤紼嬪簭鏃訛紝瀵硅祫婧愰噺鐨勯浼拌鐗瑰埆淇濆畧鍜岃皚鎱庛?/p>
澶勭悊璧勬簮涓嶈凍鐨勯棶棰樻槸鍗佸垎澶嶆潅鐨勶紝鍥犱負鍙戠敓涓婅堪鎯呭喌鏃朵綘涓嶄細鏀跺埌鐗瑰埆鐨勯敊璇唬鐮侊紝閫氬父浣犲彧鑳芥敹鍒頒竴鑸х殑WSAENOBUFS鎴栬匛RROR_INSUFFICIENT_RESOURCES 閿欒銆傝澶勭悊榪欎簺閿欒錛岄鍏堬紝鎶婁綘鐨勫簲鐢ㄧ▼搴忓伐浣滈厤緗皟鏁村埌鍚堢悊鐨勬渶澶у?璇戣呮敞錛氭墍璋撳伐浣滈厤緗紝鏄寚搴旂敤紼嬪簭鍚勯儴鍒嗚繍琛屼腑鎵闇鐨勫唴瀛樼敤閲忥紝璇峰弬鑰?http://msdn.microsoft.com/msdnmag/issues/1000/Bugslayer/Bugslayer1000.asp 錛屽叧浜庡唴瀛樹紭鍖栵紝璇戣呭彟鏈夎瘧鏂?錛屽鏋滈敊璇戶緇嚭鐜幫紝閭d箞娉ㄦ剰媯鏌ユ槸鍚︽槸緗戠粶甯﹀涓嶈凍鐨勯棶棰樸備箣鍚庯紝璇風‘璁や綘娌℃湁鍚屾椂鍙戝嚭澶鐨勬敹鍙戣皟鐢ㄣ傛渶鍚庯紝濡傛灉榪樻槸鏀跺埌璧勬簮涓嶈凍鐨勯敊璇紝閭e氨寰堝彲鑳芥槸閬囧埌浜嗘湭鍒嗛〉鍐呭瓨姹犱笉瓚崇殑闂浜嗐傝閲婃斁鏈垎欏靛唴瀛樻睜絀洪棿錛岃鍏抽棴搴旂敤紼嬪簭涓浉褰撻儴鍒嗙殑榪炴帴錛岀瓑寰呯郴緇熻嚜琛屾浮榪囧拰淇榪欎釜鐬椂鐨勯敊璇?br>
鎺ュ彈榪炴帴璇鋒眰
鏈嶅姟鍣ㄨ鍋氱殑鏈鏅氱殑浜嬫儏涔嬩竴灝辨槸鎺ュ彈鏉ヨ嚜瀹㈡埛绔殑榪炴帴璇鋒眰銆傚湪濂楁帴瀛椾笂浣跨敤閲嶅彔I/O鎺ュ彈榪炴帴鐨勬儫涓API灝辨槸AcceptEx()鍑芥暟銆傛湁瓚g殑鏄紝閫氬父鐨勫悓姝ユ帴鍙楀嚱鏁癮ccept()鐨勮繑鍥炲兼槸涓涓柊鐨勫鎺ュ瓧錛岃孉cceptEx()鍑芥暟鍒欓渶瑕佸彟澶栦竴涓鎺ュ瓧浣滀負瀹冪殑鍙傛暟涔嬩竴銆傝繖鏄洜涓篈cceptEx()鏄竴涓噸鍙犳搷浣滐紝鎵浠ヤ綘闇瑕佷簨鍏堝垱寤轟竴涓鎺ュ瓧(浣嗕笉瑕佺粦瀹氭垨榪炴帴瀹?錛屽茍鎶婅繖涓鎺ュ瓧閫氳繃鍙傛暟浼犵粰AcceptEx()銆備互涓嬫槸涓灝忔鍏稿瀷鐨勪嬌鐢ˋcceptEx()鐨勪吉浠g爜錛?
do {
-絳夊緟涓婁竴涓?AcceptEx 瀹屾垚
-鍒涘緩涓涓柊濂楁帴瀛楀茍涓庡畬鎴愮鍙h繘琛屽叧鑱?
-璁劇疆鑳屾櫙緇撴瀯絳夌瓑
-鍙戝嚭涓涓?AcceptEx 璇鋒眰
}while(TRUE);
浣滀負涓涓珮鍝嶅簲鑳藉姏鐨勬湇鍔″櫒錛屽畠蹇呴』鍙戝嚭瓚沖鐨凙cceptEx璋冪敤錛屽畧鍊欑潃錛屼竴鏃﹀嚭鐜板鎴風榪炴帴璇鋒眰灝辯珛鍒誨搷搴斻傝嚦浜庡彂鍑哄灝戜釜AcceptEx鎵嶅錛屽氨鍙栧喅浜庝綘鐨勬湇鍔″櫒紼嬪簭鎵鏈熷緟鐨勯氫俊浜ら氱被鍨嬨傛瘮濡傦紝濡傛灉榪涘叆榪炴帴鐜囬珮鐨勬儏鍐?鍥犱負榪炴帴鎸佺畫鏃墮棿杈冪煭錛屾垨鑰呭嚭鐜頒氦閫氶珮宄?錛岄偅涔堟墍闇瑕佸畧鍊欑殑AcceptEx褰撶劧瑕佹瘮閭d簺鍋跺皵榪涘叆鐨勫鎴風榪炴帴鐨勬儏鍐佃澶氥傝仾鏄庣殑鍋氭硶鏄紝鐢卞簲鐢ㄧ▼搴忔潵鍒嗘瀽浜ら氱姸鍐碉紝騫惰皟鏁碅cceptEx瀹堝欑殑鏁伴噺錛岃屼笉鏄浐瀹氬湪鏌愪釜鏁伴噺涓娿?
瀵逛簬Windows2000錛學insock鎻愪緵浜嗕竴浜涙満鍒訛紝甯姪浣犲垽瀹欰cceptEx鐨勬暟閲忔槸鍚﹁凍澶熴傝繖灝辨槸錛屽湪鍒涘緩鐩戝惉濂楁帴瀛楁椂鍒涘緩涓涓簨浠訛紝閫氳繃WSAEventSelect()榪欎釜API騫舵敞鍐孎D_ACCEPT浜嬩歡閫氱煡鏉ユ妸濂楁帴瀛楀拰榪欎釜浜嬩歡鍏寵仈璧鋒潵銆備竴鏃︾郴緇熸敹鍒頒竴涓繛鎺ヨ姹傦紝濡傛灉緋葷粺涓病鏈堿cceptEx()姝e湪絳夊緟鎺ュ彈榪炴帴錛岄偅涔堜笂闈㈢殑浜嬩歡灝嗘敹鍒頒竴涓俊鍙楓傞氳繃榪欎釜浜嬩歡錛屼綘灝卞彲浠ュ垽鏂綘鏈夋病鏈夊彂鍑鴻凍澶熺殑AcceptEx()錛屾垨鑰呮嫻嬪嚭涓涓潪姝e父鐨勫鎴瘋姹?涓嬫枃榪?銆傝繖縐嶆満鍒跺Windows NT 4.0涓嶉傜敤銆?/p>
浣跨敤AcceptEx()鐨勪竴澶уソ澶勬槸錛屼綘鍙互閫氳繃涓嬈¤皟鐢ㄥ氨瀹屾垚鎺ュ彈瀹㈡埛绔繛鎺ヨ姹傚拰鎺ュ彈鏁版嵁(閫氳繃浼犻乴pOutputBuffer鍙傛暟)涓や歡浜嬫儏銆備篃灝辨槸璇達紝濡傛灉瀹㈡埛绔湪鍙戝嚭榪炴帴鐨勫悓鏃朵紶杈撴暟鎹紝浣犵殑AcceptEx()璋冪敤鍦ㄨ繛鎺ュ垱寤哄茍鎺ユ敹浜嗗鎴風鏁版嵁鍚庡氨鍙互绔嬪埢榪斿洖銆傝繖鏍峰彲鑳芥槸寰堟湁鐢ㄧ殑錛屼絾鏄篃鍙兘浼氬紩鍙戦棶棰橈紝鍥犱負AcceptEx()蹇呴』絳夊叏閮ㄥ鎴風鏁版嵁閮芥敹鍒頒簡鎵嶈繑鍥炪傚叿浣撴潵璇達紝濡傛灉浣犲湪鍙戝嚭AcceptEx()璋冪敤鐨勫悓鏃朵紶閫掍簡lpOutputBuffer鍙傛暟錛岄偅涔圓cceptEx()涓嶅啀鏄竴欏瑰師瀛愬瀷鐨勬搷浣滐紝鑰屾槸鍒嗘垚浜嗕袱姝ワ細鎺ュ彈瀹㈡埛榪炴帴錛岀瓑寰呮帴鏀舵暟鎹傚綋緙哄皯涓縐嶆満鍒舵潵閫氱煡浣犵殑搴旂敤紼嬪簭鎵鍙戠敓鐨勮繖縐嶆儏鍐碉細“榪炴帴宸茬粡寤虹珛浜嗭紝姝e湪絳夊緟瀹㈡埛绔暟鎹?#8221;錛岃繖灝嗘剰鍛崇潃鏈夊彲鑳藉嚭鐜板鎴風鍙彂鍑鴻繛鎺ヨ姹傦紝浣嗘槸涓嶅彂閫佹暟鎹傚鏋滀綘鐨勬湇鍔″櫒鏀跺埌澶榪欑綾誨瀷鐨勮繛鎺ユ椂錛屽畠灝嗘嫆緇濊繛鎺ユ洿澶氱殑鍚堟硶瀹㈡埛绔姹傘傝繖灝辨槸榛戝榪涜“鎷掔粷鏈嶅姟”鏀誨嚮鐨勫父瑙佹墜娉曘?/p>
瑕侀闃叉綾繪敾鍑伙紝鎺ュ彈榪炴帴鐨勭嚎紼嬪簲璇ヤ笉鏃跺湴閫氳繃璋冪敤getsockopt()鍑芥暟(閫夐」鍙傛暟涓篠O_CONNECT_TIME)鏉ユ鏌cceptEx()閲屽畧鍊欑殑濂楁帴瀛椼俫etsockopt()鍑芥暟鐨勯夐」鍊煎皢琚緗負濂楁帴瀛楄榪炴帴鐨勬椂闂達紝鎴栬呰緗負-1(浠h〃濂楁帴瀛楀皻鏈緩绔嬭繛鎺?銆傝繖鏃訛紝WSAEventSelect()鐨勭壒鎬у氨鍙互寰堝ソ鍦板埄鐢ㄦ潵鍋氳繖縐嶆鏌ャ傚鏋滃彂鐜拌繛鎺ュ凡緇忓緩绔嬶紝浣嗘槸寰堜箙閮芥病鏈夋敹鍒版暟鎹殑鎯呭喌錛岄偅涔堝氨搴旇緇堟榪炴帴錛屾柟娉曞氨鏄叧闂綔涓哄弬鏁版彁渚涚粰AcceptEx()鐨勯偅涓鎺ュ瓧銆傛敞鎰忥紝鍦ㄥ鏁伴潪绱фユ儏鍐典笅錛屽鏋滃鎺ュ瓧宸茬粡浼犻掔粰AcceptEx()騫跺紑濮嬪畧鍊欙紝浣嗚繕鏈緩绔嬭繛鎺ワ紝閭d箞浣犵殑搴旂敤紼嬪簭涓嶅簲璇ュ叧闂畠浠傝繖鏄洜涓哄嵆浣垮叧闂簡榪欎簺濂楁帴瀛楋紝鍑轟簬鎻愰珮緋葷粺鎬ц兘鐨勮冭檻錛屽湪榪炴帴榪涘叆涔嬪墠錛屾垨鑰呯洃鍚鎺ュ瓧鑷韓琚叧闂箣鍓嶏紝鐩稿簲鐨勫唴鏍告ā寮忕殑鏁版嵁緇撴瀯涔熶笉浼氳騫插噣鍦版竻闄ゃ?/p>
鍙戝嚭AcceptEx()璋冪敤鐨勭嚎紼嬶紝浼間箮涓庨偅涓繘琛屽畬鎴愮鍙e叧鑱旀搷浣溿佸鐞嗗叾瀹僆/O瀹屾垚閫氱煡鐨勭嚎紼嬫槸鍚屼竴涓紝浣嗘槸錛屽埆蹇樿綰跨▼閲屽簲璇ュ敖鍔涢伩鍏嶆墽琛岄樆濉炲瀷鐨勬搷浣溿俉insock2鍒嗗眰緇撴瀯鐨勪竴涓壇浣滅敤鏄皟鐢╯ocket()鎴朩SASocket() API鐨勪笂灞傛灦鏋勫彲鑳藉緢閲嶈(璇戣呬笉澶槑鐧藉師鏂囨剰鎬濓紝鎶辨瓑)銆傛瘡涓狝cceptEx()璋冪敤閮介渶瑕佸垱寤轟竴涓柊濂楁帴瀛楋紝鎵浠ユ渶濂芥湁涓涓嫭绔嬬殑綰跨▼涓撻棬璋冪敤AcceptEx()錛岃屼笉鍙備笌鍏跺畠I/O澶勭悊銆備綘涔熷彲浠ュ埄鐢ㄨ繖涓嚎紼嬫潵鎵ц鍏跺畠浠誨姟錛屾瘮濡備簨浠惰褰曘?/p>
鏈夊叧AcceptEx()鐨勬渶鍚庝竴涓敞鎰忎簨欏癸細瑕佸疄鐜拌繖浜汚PI錛屽茍涓嶉渶瑕佸叾瀹冩彁渚涘晢鎻愪緵鐨刉insock2瀹炵幇銆傝繖涓鐐瑰寰蔣鐗規湁鐨勫叾瀹傾PI涔熷悓鏍烽傜敤錛屾瘮濡俆ransmitFile()鍜孏etAcceptExSockAddrs()錛屼互鍙婂叾瀹冨彲鑳戒細琚姞鍏ュ埌鏂扮増Windows鐨凙PI. 鍦╓indows NT鍜?000涓婏紝榪欎簺API鏄湪寰蔣鐨勫簳灞傛彁渚涜匘LL(mswsock.dll)涓疄鐜扮殑錛屽彲閫氳繃涓巑swsock.lib緙栬瘧榪炴帴榪涜璋冪敤錛屾垨鑰呴氳繃WSAIoctl() (閫夐」鍙傛暟涓篠IO_GET_EXTENSION_FUNCTION_POINTER)鍔ㄦ佽幏寰楀嚱鏁扮殑鎸囬拡銆?/p>
濡傛灉鍦ㄦ病鏈変簨鍏堣幏寰楀嚱鏁版寚閽堢殑鎯呭喌涓嬬洿鎺ヨ皟鐢ㄥ嚱鏁?涔熷氨鏄錛岀紪璇戞椂闈欐佽繛鎺swsock.lib錛屽湪紼嬪簭涓洿鎺ヨ皟鐢ㄥ嚱鏁?錛岄偅涔堟ц兘灝嗗緢鍙楀獎鍝嶃傚洜涓篈cceptEx()琚疆浜嶹insock2鏋舵瀯涔嬪錛屾瘡嬈¤皟鐢ㄦ椂瀹冮兘琚揩閫氳繃WSAIoctl()鍙栧緱鍑芥暟鎸囬拡銆傝閬垮厤榪欑鎬ц兘鎹熷け錛岄渶瑕佷嬌鐢ㄨ繖浜汚PI鐨勫簲鐢ㄧ▼搴忓簲璇ラ氳繃璋冪敤WSAIoctl()鐩存帴浠庡簳灞傜殑鎻愪緵鑰呴偅閲屽彇寰楀嚱鏁扮殑鎸囬拡銆?br>
鍙傝涓嬪浘濂楁帴瀛楁灦鏋勶細
TransmitFile 鍜?TransmitPackets
Winsock 鎻愪緵涓や釜涓撻棬涓烘枃浠跺拰鍐呭瓨鏁版嵁浼犺緭榪涜浜嗕紭鍖栫殑鍑芥暟銆傚叾涓璗ransmitFile()榪欎釜API鍑芥暟鍦╓indows NT 4.0 鍜?Windows 2000涓婇兘鍙互浣跨敤錛岃孴ransmitPackets()鍒欏皢鍦ㄦ湭鏉ョ増鏈殑Windows涓疄鐜般?/p>
TransmitFile()鐢ㄦ潵鎶婃枃浠跺唴瀹歸氳繃Winsock榪涜浼犺緭銆傞氬父鍙戦佹枃浠剁殑鍋氭硶鏄紝鍏堣皟鐢–reateFile()鎵撳紑涓涓枃浠訛紝鐒跺悗涓嶆柇寰幆璋冪敤ReadFile() 鍜學SASend ()鐩磋嚦鏁版嵁鍙戦佸畬姣曘備絾鏄繖縐嶆柟娉曞緢娌℃湁鏁堢巼錛屽洜涓烘瘡嬈¤皟鐢≧eadFile() 鍜?WSASend ()閮戒細娑夊強涓嬈′粠鐢ㄦ埛妯″紡鍒板唴鏍告ā寮忕殑杞崲銆傚鏋滄崲鎴怲ransmitFile()錛岄偅涔堝彧闇瑕佺粰瀹冧竴涓凡鎵撳紑鏂囦歡鐨勫彞鏌勫拰瑕佸彂閫佺殑瀛楄妭鏁幫紝鑰屾墍娑夊強鐨勬ā寮忚漿鎹㈡搷浣滃皢鍙湪璋冪敤CreateFile()鎵撳紑鏂囦歡鏃跺彂鐢熶竴嬈★紝鐒跺悗TransmitFile()鏃跺啀鍙戠敓涓嬈°傝繖鏍鋒晥鐜囧氨楂樺浜嗐?/p>
TransmitPackets()姣擳ransmitFile()鏇磋繘涓姝ワ紝瀹冨厑璁哥敤鎴峰彧璋冪敤涓嬈″氨鍙互鍙戦佹寚瀹氱殑澶氫釜鏂囦歡鍜屽唴瀛樼紦鍐插尯銆傚嚱鏁板師鍨嬪涓嬶細
BOOL TransmitPackets( SOCKET hSocket, LPTRANSMIT_PACKET_ELEMENT lpPacketArray, DWORD nElementCount, DWORD nSendSize, LPOVERLAPPED lpOverlapped, DWORD dwFlags );鍏朵腑錛宭pPacketArray鏄竴涓粨鏋勭殑鏁扮粍錛屽叾涓殑姣忎釜鍏冪礌鏃㈠彲浠ユ槸涓涓枃浠跺彞鏌勬垨鑰呭唴瀛樼紦鍐插尯錛岃緇撴瀯瀹氫箟濡備笅錛?br>
typedef struct _TRANSMIT_PACKETS_ELEMENT {
DWORD dwElFlags;
DWORD cLength;
union {
struct {
LARGE_INTEGER nFileOffset;
HANDLE hFile;
};
PVOID pBuffer;
};
} TRANSMIT_FILE_BUFFERS;
鍏朵腑鍚勫瓧孌墊槸鑷弿榪板瀷鐨?self explanatory)銆?br>dwElFlags瀛楁錛氭寚瀹氬綋鍓嶅厓绱犳槸涓涓枃浠跺彞鏌勮繕鏄唴瀛樼紦鍐插尯(鍒嗗埆閫氳繃甯擱噺TF_ELEMENT_FILE 鍜孴F_ELEMENT_MEMORY鎸囧畾)錛?br>cLength瀛楁錛氭寚瀹氬皢浠庢暟鎹簮鍙戦佺殑瀛楄妭鏁?濡傛灉鏄枃浠訛紝榪欎釜瀛楁鍊間負0琛ㄧず鍙戦佹暣涓枃浠?錛?br>緇撴瀯涓殑鏃犲悕鑱斿悎浣擄細鍖呭惈鏂囦歡鍙ユ焺鐨勫唴瀛樼紦鍐插尯(浠ュ強鍙兘鐨勫亸縐婚噺)銆?
浣跨敤榪欎袱涓狝PI鐨勫彟涓涓ソ澶勶紝鏄彲浠ラ氳繃鎸囧畾TF_REUSE_SOCKET鍜孴F_DISCONNECT鏍囧織鏉ラ噸鐢ㄥ鎺ュ瓧鍙ユ焺銆傛瘡褰揂PI瀹屾垚鏁版嵁鐨勪紶杈撳伐浣滃悗錛屽氨浼氬湪浼犺緭灞傜駭鍒柇寮榪炴帴錛岃繖鏍瘋繖涓鎺ュ瓧灝卞張鍙互閲嶆柊鎻愪緵緇橝cceptEx()浣跨敤銆傞噰鐢ㄨ繖縐嶄紭鍖栫殑鏂規硶緙栫▼錛屽皢鍑忚交閭d釜涓撻棬鍋氭帴鍙楁搷浣滅殑綰跨▼鍒涘緩濂楁帴瀛楃殑鍘嬪姏(鍓嶆枃榪板強)銆?/p>
榪欎袱涓狝PI涔熼兘鏈変竴涓叡鍚岀殑寮辯偣錛歐indows NT Workstation 鎴?Windows 2000 涓撲笟鐗堜腑錛屽嚱鏁版瘡嬈″彧鑳藉鐞嗕袱涓皟鐢ㄨ姹傦紝鍙湁鍦╓indows NT銆乄indows 2000鏈嶅姟鍣ㄧ増銆乄indows 2000楂樼駭鏈嶅姟鍣ㄧ増鎴?Windows 2000 Data Center涓墠鑾峰緱瀹屽叏鏀寔銆?/p>
鏀懼湪涓璧風湅鐪?/strong>
浠ヤ笂鍚勮妭涓紝鎴戜滑璁ㄨ浜嗗紑鍙戦珮鎬ц兘鐨勩佸ぇ鍝嶅簲瑙勬ā鐨勫簲鐢ㄧ▼搴忔墍闇鐨勫嚱鏁般佹柟娉曞拰鍙兘閬囧埌鐨勮祫婧愮摱棰堥棶棰樸傝繖浜涘浣犳剰鍛崇潃浠涔堝憿錛熷叾瀹烇紝榪欏彇鍐充簬浣犲浣曟瀯閫犱綘鐨勬湇鍔″櫒鍜屽鎴風銆傚綋浣犺兘澶熷湪鏈嶅姟鍣ㄥ拰瀹㈡埛绔璁′笂榪涜鏇村ソ鍦版帶鍒舵椂錛岄偅涔堜綘瓚婅兘澶熼伩寮鐡墮闂銆?/p>
鏉ョ湅涓涓ず鑼冪殑鐜銆傛垜浠璁捐涓涓湇鍔″櫒鏉ュ搷搴斿鎴風鐨勮繛鎺ャ佸彂閫佽姹傘佹帴鏀舵暟鎹互鍙婃柇寮榪炴帴銆傞偅涔堬紝鏈嶅姟鍣ㄥ皢闇瑕佸垱寤轟竴涓洃鍚鎺ュ瓧錛屾妸瀹冧笌鏌愪釜瀹屾垚绔彛榪涜鍏寵仈錛屼負姣忛CPU鍒涘緩涓涓伐浣滅嚎紼嬨傚啀鍒涘緩涓涓嚎紼嬩笓闂ㄧ敤鏉ュ彂鍑篈cceptEx()銆傛垜浠煡閬撳鎴風浼氬湪鍙戝嚭榪炴帴璇鋒眰鍚庣珛鍒諱紶閫佹暟鎹紝鎵浠ュ鏋滄垜浠噯澶囧ソ鎺ユ敹緙撳啿鍖轟細浣夸簨鎯呭彉寰楁洿涓哄鏄撱傚綋鐒訛紝涓嶈蹇樿涓嶆椂鍦拌疆璇cceptEx()璋冪敤涓嬌鐢ㄧ殑濂楁帴瀛?浣跨敤SO_CONNECT_TIME閫夐」鍙傛暟)鏉ョ‘淇濇病鏈夋伓鎰忚秴鏃剁殑榪炴帴銆?/p>
璇ヨ璁′腑鏈変竴涓噸瑕佺殑闂瑕佽冭檻錛屾垜浠簲璇ュ厑璁稿灝戜釜AcceptEx()榪涜瀹堝欍傝繖鏄洜涓猴紝姣忓彂鍑轟竴涓狝cceptEx()鏃舵垜浠兘鍚屾椂闇瑕佷負瀹冩彁渚涗竴涓帴鏀剁紦鍐插尯錛岄偅涔堝唴瀛樹腑灝嗕細鍑虹幇寰堝琚攣瀹氱殑欏甸潰(鍓嶆枃璇磋繃浜嗭紝姣忎釜閲嶅彔鎿嶄綔閮戒細娑堣椾竴灝忛儴鍒嗘湭鍒嗛〉鍐呭瓨姹狅紝鍚屾椂榪樹細閿佸畾鎵鏈夋秹鍙婄殑緙撳啿鍖?銆傝繖涓棶棰樺緢闅懼洖絳旓紝娌℃湁涓涓‘鍒囩殑絳旀銆傛渶濂界殑鏂規硶鏄妸榪欎釜鍊煎仛鎴愬彲浠ヨ皟鏁寸殑錛岄氳繃鍙嶅鍋氭ц兘嫻嬭瘯錛屼綘灝卞彲浠ュ緱鍑哄湪鍏稿瀷搴旂敤鐜涓渶浣崇殑鍊箋?/p>
濂戒簡錛屽綋浣犳祴綆楁竻妤氬悗錛屼笅闈㈠氨鏄彂閫佹暟鎹殑闂浜嗭紝鑰冭檻鐨勯噸鐐規槸浣犲笇鏈涙湇鍔″櫒鍚屾椂澶勭悊澶氬皯涓茍鍙戠殑榪炴帴銆傞氬父鎯呭喌涓嬶紝鏈嶅姟鍣ㄥ簲璇ラ檺鍒跺茍鍙戣繛鎺ョ殑鏁伴噺浠ュ強絳夊欏鐞嗙殑鍙戦佽皟鐢ㄣ傚洜涓哄茍鍙戣繛鎺ユ暟閲忚秺澶氾紝鎵娑堣楃殑鏈垎欏靛唴瀛樻睜涔熻秺澶氾紱絳夊欏鐞嗙殑鍙戦佽皟鐢ㄨ秺澶氾紝琚攣瀹氱殑鍐呭瓨欏甸潰涔熻秺澶?灝忓績鍒秴榪囦簡鏋侀檺)銆傝繖鍚屾牱涔熼渶瑕佸弽澶嶆祴璇曟墠鐭ラ亾絳旀銆?/p>
瀵逛簬涓婅堪鐜錛岄氬父涓嶉渶瑕佸叧闂崟涓鎺ュ瓧鐨勭紦鍐插尯錛屽洜涓哄彧鍦ˋcceptEx()涓湁涓嬈℃帴鏀舵暟鎹殑鎿嶄綔錛岃岃淇濊瘉緇欐瘡涓埌鏉ョ殑榪炴帴鎻愪緵鎺ユ敹緙撳啿鍖哄茍涓嶆槸澶毦鐨勪簨鎯呫備絾鏄紝濡傛灉瀹㈡埛鏈轟笌鏈嶅姟鍣ㄤ氦浜掔殑鏂瑰紡鍙樹竴鍙橈紝瀹㈡埛鏈哄湪鍙戦佷簡涓嬈℃暟鎹箣鍚庯紝榪橀渶瑕佸彂閫佹洿澶氱殑鏁版嵁錛屽湪榪欑鎯呭喌涓嬪叧闂帴鏀剁紦鍐插氨涓嶅お濡欎簡錛岄櫎闈炰綘鎯沖姙娉曚繚璇佸湪姣忎釜榪炴帴涓婇兘鍙戝嚭浜嗛噸鍙犳帴鏀惰皟鐢ㄦ潵鎺ユ敹鏇村鐨勬暟鎹?/p>
緇撹
寮鍙戝ぇ鍝嶅簲瑙勬ā鐨刉insock鏈嶅姟鍣ㄥ茍涓嶆槸寰堝彲鎬曪紝鍏跺疄涔熷氨鏄緗竴涓洃鍚鎺ュ瓧銆佹帴鍙楄繛鎺ヨ姹傚拰榪涜閲嶅彔鏀跺彂璋冪敤銆傞氳繃璁劇疆鍚堢悊鐨勮繘琛屽畧鍊欑殑閲嶅彔璋冪敤鐨勬暟閲忥紝闃叉鍑虹幇鏈垎欏靛唴瀛樻睜琚楀敖錛岃繖鎵嶆槸鏈涓昏鐨勬寫鎴樸傛寜鐓ф垜浠墠闈㈣璁虹殑涓浜涘師鍒欙紝浣犲氨鍙互寮鍙戝嚭澶у搷搴旇妯$殑鏈嶅姟鍣ㄥ簲鐢ㄧ▼搴忋?br>
涓嬮潰鎴戠粰鍑烘敮鎸佸崟涓猄ocket鍙婃敮鎸佸涓猄ocket鐨凜onsole紼嬪簭浠g爜銆傚厛鏉ョ湅鐪嬫敮鎸佸崟涓猄ocket鐨勭▼搴?鑰冭檻鍒頒唬鐮佺畝媧佹э紝鍙粰涓涓鏋訛紝鍚屾椂涓嶈繘琛屽嚭閿欏鐞嗐?br>int main()
{
WSAOVERLAPPED Overlapped;
// 鍚姩Winsock鍙婂緩绔嬬洃鍚鎺ュ瓧
listen(hListenSocket, 5);
hClientSocket = accept(hListenSocket, NULL, NULL);
ZeroMemory(&Overlapped, sizeof(WSAOVERLAPPED));
nResult = WSARecv(...); // 鍙戝嚭璇鋒眰
for (; ;)
{
bResult = WSAGetOverlappedResult(...);
// 鍑芥暟榪斿洖鍚庤繘琛岀浉搴旂殑澶勭悊
nResult = WSARecv(...); // 鍙戝嚭鍙﹀涓涓姹?br> }
}
涓婇潰鐨勭▼搴忓彧鏄兂璇存槑涓涓嬭繃紼嬶紝紼嬪簭娌℃湁瀹炵幇浠涔堝姛鑳姐傝繖鏍峰仛鐨勭洰鐨勬槸鑺傜害瀛楁暟錛岀敤鏉ヨ鏄庢垜涓嬮潰鏀寔澶氫釜Socket鐨凜onsole搴旂敤銆傝緇х畫鐪嬨?br> 鍏堢湅涓涓嚜瀹氫箟鐨勭粨鏋勪綋錛屽崟鍙ユ焺鏁版嵁緇撴瀯錛岄氳繃璇ョ粨鏋?涓葷嚎紼嬩笌鏌愪釜鐗瑰畾鐨勫瓙綰跨▼涓殑濂楁帴瀛楃浉浜掕仈緋匯?br> typedef struct _PER_HANDLE_DATA
{
SOCKET hSocket; // 涓婚敭:閫氫俊濂楁帴瀛?br> char szClientIP[16];// 鑷畾涔夊瓧孌?瀹㈡埛绔湴鍧
int nOperateType; // 鑷畾涔夊瓧孌?鎿嶄綔綾誨瀷
}PER_HANDLE_DATA, FAR* LPPER_HANDLE_DATA;
鍦ㄤ笂闈㈢殑緇撴瀯涓繕鍙互鍔犲叆鑷繁闇瑕佺殑瀛楁銆傚湪鎴戜笅闈㈢殑渚嬪瓙紼嬪簭涓紝szClientIP鏄敤鏉ヤ繚瀛樿繛鎺ヤ笂鏉ョ殑瀹㈡埛绔殑IP鐨勶紝榪欐牱鍦ㄤ富綰跨▼灝嗚繖涓粨鏋勪綋浼犵粰瀛愮嚎紼嬪悗錛屽湪瀛愮嚎紼嬩腑鏍規嵁瀹㈡埛绔疘P灝辯煡閬撶洰鍓嶅鐞嗙殑鏄摢涓鎴風浜嗐備笅闈㈡槸紼嬪簭鐨勫ぇ閮ㄥ垎錛屽悓鏍烽櫎鍘諱竴浜涚畝鍗曠殑鍑洪敊杈撳嚭銆?br>#define LISTEN_PORT 5000
#define DATA_BUFSIZE 8192
#define POST_RECV 0X01
#define POST_SEND 0X02
int main( )
{
LPPER_HANDLE_DATA lpPerHandleData;
SOCKET hListenSocket;
SOCKET hClientSocket;
SOCKADDR_IN ClientAddr;
int nAddrLen;
HANDLE hThread;
// Start WinSock and create a listen socket.
listen(hListenSocket, 5);
for (; ;)
{
nAddrLen = sizeof(SOCKADDR);
hClientSocket = accept(hListenSocket, (LPSOCKADDR)&ClientAddr, &nAddrLen);
lpPerHandleData = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
lpPerHandleData->hSocket = hClientSocket;
// 娉ㄦ剰榪欓噷灝嗚繛鎺ョ殑瀹㈡埛绔殑IP鍦板潃錛屼繚瀛樺埌浜唋pPerHandleData瀛楁涓簡
strcpy(lpPerHandleData->szClientIP, inet_ntoa(ClientAddr.sin_addr));
// 涓烘湰嬈″鎴瘋姹備駭鐢熷瓙綰跨▼
hThread = CreateThread(
NULL,
0,
OverlappedThread,
lpPerHandleData, // 灝唋pPerHandleData浼犵粰瀛愮嚎紼?br> 0,
NULL
);
CloseHandle(hThread);
}
return 0;
}
DWORD WINAPI OverlappedThread(LPVOID lpParam)
{
LPPER_HANDLE_DATA lpPerHandleData = (LPPER_HANDLE_DATA)lpParam;
WSAOVERLAPPED Overlapped;
WSABUF wsaBuf;
char Buffer[DATA_BUFSIZE];
BOOL bResult;
int nResult;
ZeroMemory(&Overlapped, sizeof(WSAOVERLAPPED));
wsaBuf.buf = Buffer;
wsaBuf.len = sizeof(Buffer);
lpPerHandleData->nOperateType = POST_RECV; // 璁板綍鏈鎿嶄綔鏄疪ecv(..)
dwFlags = 0;
nResult = WSARecv(
lpPerHandleData->hSocket, // Receive socket
&wsaBuf, // 鎸囧悜WSABUF緇撴瀯鐨勬寚閽?br> 1, // WSABUF鏁扮粍鐨勪釜鏁?br> &dwNumOfBytesRecved, // 瀛樻斁褰揥SARecv瀹屾垚鍚庢墍鎺ユ敹鍒扮殑瀛楄妭鏁?br> &dwFlags, // A pointer to flags
&Overlapped, // A pointer to a WSAOVERLAPPED structure
NULL // A pointer to the completion routine,this is NULL
);
if ( nResult == SOCKET_ERROR && GetLastError() != WSA_IO_PENDING)
{
printf("WSARecv(..) failed.\n");
free(lpPerHandleData);
return 1;
}
while (TRUE)
{
bResult = WSAGetOverlappedResult(
lpPerHandleData->hSocket,
&Overlapped,
&dwBytesTransferred, // 褰撲竴涓悓姝/O瀹屾垚鍚?鎺ユ敹鍒扮殑瀛楄妭鏁?br> TRUE, // 絳夊緟I/O鎿嶄綔鐨勫畬鎴?
&dwFlags
);
if (bResult == FALSE && WSAGetLastError() != WSA_IO_INCOMPLETE)
{
printf("WSAGetOverlappdResult(..) failed.\n");
free(lpPerHandleData);
return 1; // 閿欒閫鍑?br> }
if (dwBytesTransferred == 0)
{
printf("瀹㈡埛绔凡閫鍑?灝嗘柇寮涓庝箣鐨勮繛鎺?\n");
closesocket(lpPerHandleData->hSocket);
free(lpPerHandleData);
break;
}
// 鍦ㄨ繖閲屽皢鎺ユ敹鍒扮殑鏁版嵁榪涜澶勭悊
printf("Received from IP: %s.\ndata: %s\n", lpPerHandleData->szClientIP, wsaBuf.buf);
// 鍙戦佸彟澶栦竴涓姹傛搷浣?br> ZeroMemory(&Overlapped, sizeof(WSAOVERLAPPED));
lpPerHandleData->nOperateType = POST_RECV;
dwFlags = 0;
nResult = WSARecv(...);
if (...){}
}
return 0;
}
紼嬪簭緇撴瀯姣旇緝娓呮櫚錛宭pPerHandleData鏄富綰跨▼涓庡瓙綰跨▼鑱旂郴鐨勭航甯︼紝瀛愮嚎紼嬫槸閫氳繃榪欎釜緇撴瀯鑾峰緱鎵澶勭悊瀹㈡埛绔殑鎯呭喌鐨勩傚湪涓嶅悓鐨勫簲鐢ㄤ腑鍙互灝嗚繖涓粨鏋勫畾涔夋垚涓嶅悓鐨勫艦寮忥紝浠ョ鍚堟墍瀹炵幇搴旂敤鐨勯渶瑕併傛敞鎰忕粨鏋勪綋鐨刵OperateType鍦℅etOverlappedResult榪斿洖鏃剁敤鍒?鍙互鏍規嵁榪欎釜瀛楁紜畾鎴戜滑涓嬩竴姝ョ殑鎿嶄綔銆傝鏈嬪弸浠鎻愭剰瑙佷簡銆?/font>
鈥滃畬鎴愮鍙b濇ā鍨嬫槸榪勪粖涓烘鏈涓哄鏉傜殑涓縐岻/O妯″瀷銆傜劧鑰岋紝鍋囪嫢涓涓簲鐢ㄧ▼搴忓悓鏃墮渶瑕佺鐞嗕負鏁頒紬澶氱殑濂楁帴瀛楋紝閭d箞閲囩敤榪欑妯″瀷錛屽線寰鍙互杈懼埌鏈浣崇殑緋葷粺鎬ц兘錛?/p>
浠庢湰璐ㄤ笂璇達紝瀹屾垚绔彛妯″瀷瑕佹眰鎴戜滑鍒涘緩涓涓猈in32瀹屾垚绔彛瀵硅薄錛岄氳繃鎸囧畾鏁伴噺鐨勭嚎紼嬶紝瀵歸噸鍙營/O璇鋒眰榪涜綆$悊錛屼互渚夸負宸茬粡瀹屾垚鐨勯噸鍙營/O璇鋒眰鎻愪緵鏈嶅姟銆?/p>
浣跨敤榪欑妯″瀷涔嬪墠錛岄鍏堣鍒涘緩涓涓狪/O瀹屾垚绔彛瀵硅薄錛岀敤瀹冮潰鍚戜換鎰忔暟閲忕殑濂楁帴瀛楀彞鏌勶紝綆$悊澶氫釜I/O璇鋒眰銆傝鍋氬埌榪欎竴鐐癸紝闇瑕佽皟鐢–reateCompletionPort鍑芥暟銆?br />璇ュ嚱鏁板畾涔夊涓嬶細
HANDLE CreateIoCompletionPort(
聽聽聽 HANDLE FileHandle,
聽聽聽 HANDLE ExistingCompletionPort,
聽聽聽 ULONG_PTR CompletionKey,
聽聽聽 DWORD NumberOfConcurrentThreads
);
鍦ㄦ垜浠繁鍏ユ帰璁ㄥ叾涓殑鍚勪釜鍙傛暟涔嬪墠錛岄鍏堣娉ㄦ剰璇ュ嚱鏁板疄闄呯敤浜庝袱涓槑鏄炬湁鍒殑鐩殑錛?br />1. 鐢ㄤ簬鍒涘緩涓涓畬鎴愮鍙e璞°?br />2. 灝嗕竴涓彞鏌勫悓瀹屾垚绔彛鍏寵仈鍒頒竴璧楓?
鏈寮濮嬪垱寤轟竴涓畬鎴愮鍙f椂錛屽敮涓鎰熷叴瓚g殑鍙傛暟渚挎槸NumberOfConcurrentThreads錛堝茍鍙戠嚎紼嬬殑鏁伴噺錛夛紱鍓嶉潰涓変釜鍙傛暟閮戒細琚拷鐣ャ侼umberOfConcurrentThreads鍙傛暟鐨勭壒孌婁箣澶勫湪浜庯紝瀹冨畾涔変簡鍦ㄤ竴涓畬鎴愮鍙d笂錛屽悓鏃跺厑璁告墽琛岀殑綰跨▼鏁伴噺銆傜悊鎯蟲儏鍐典笅錛屾垜浠笇鏈涙瘡涓鐞嗗櫒鍚勮嚜璐熻矗涓涓嚎紼嬬殑榪愯錛屼負瀹屾垚绔彛鎻愪緵鏈嶅姟錛岄伩鍏嶈繃浜庨綣佺殑綰跨▼鈥滃満鏅濆垏鎹€傝嫢灝嗚鍙傛暟璁句負0錛岃〃鏄庣郴緇熷唴瀹夎浜嗗灝戜釜澶勭悊鍣紝渚垮厑璁稿悓鏃惰繍琛屽灝戜釜綰跨▼錛佸彲鐢ㄤ笅榪頒唬鐮佸垱寤轟竴涓狪/O瀹屾垚绔彛錛?/p>
hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
璇ヨ鍙ョ殑浣滅敤鏄繑鍥炰竴涓彞鏌勶紝鍦ㄤ負瀹屾垚绔彛鍒嗛厤浜嗕竴涓鎺ュ瓧鍙ユ焺鍚庯紝鐢ㄦ潵瀵歸偅涓鍙h繘琛屾爣瀹氾紙寮曠敤錛夈?
涓銆佸伐浣滆呯嚎紼嬩笌瀹屾垚绔彛
鎴愬姛鍒涘緩涓涓畬鎴愮鍙e悗錛屼究鍙紑濮嬪皢濂楁帴瀛楀彞鏌勪笌瀵硅薄鍏寵仈鍒頒竴璧楓備絾鍦ㄥ叧鑱斿鎺ュ瓧涔嬪墠錛岄鍏堝繀欏誨垱寤轟竴涓垨澶氫釜鈥滃伐浣滆呯嚎紼嬧濓紝浠ヤ究鍦↖/O璇鋒眰鎶曢掔粰瀹屾垚绔彛瀵硅薄鍚庯紝涓哄畬鎴愮鍙f彁渚涙湇鍔°傚湪榪欎釜鏃跺欙紝澶у鎴栬浼氳寰楀鎬紝鍒板簳搴斿垱寤哄灝戜釜綰跨▼錛屼互渚夸負瀹屾垚绔彛鎻愪緵鏈嶅姟鍛紵榪欏疄闄呮鏄畬鎴愮鍙fā鍨嬫樉寰楅涓衡滃鏉傗濈殑涓涓柟闈紝鍥犱負鏈嶅姟I/O璇鋒眰鎵闇鐨勬暟閲忓彇鍐充簬搴旂敤紼嬪簭鐨勬諱綋璁捐鎯呭喌銆傚湪姝よ璁頒綇鐨勪竴涓噸鐐瑰湪浜庯紝鍦ㄦ垜浠皟鐢–reateIoCompletionPort鏃舵寚瀹氱殑騫跺彂綰跨▼鏁伴噺錛屼笌鎵撶畻鍒涘緩鐨勫伐浣滆呯嚎紼嬫暟閲忕浉姣旓紝瀹冧滑浠h〃鐨勫茍闈炲悓涓浠朵簨鎯呫傛棭浜涙椂鍊欙紝鎴戜滑鏇懼緩璁ぇ瀹剁敤CreateIoCompletionPort鍑芥暟涓烘瘡涓鐞嗗櫒
閮芥寚瀹氫竴涓嚎紼嬶紙澶勭悊鍣ㄧ殑鏁伴噺鏈夊灝戯紝渚挎寚瀹氬灝戠嚎紼嬶級浠ラ伩鍏嶇敱浜庨綣佺殑綰跨▼鈥滃満鏅濅氦鎹㈡椿鍔紝浠庤屽獎鍝嶇郴緇熺殑鏁翠綋鎬ц兘銆侰reateIoCompletionPort鍑芥暟鐨凬umberOfConcurrentThreads鍙傛暟鏄庣‘鎸囩ず緋葷粺錛氬湪涓涓畬鎴愮鍙d笂錛屼竴嬈″彧鍏佽n涓伐浣滆呯嚎紼嬭繍琛屻傚亣濡傚湪瀹屾垚绔彛涓婂垱寤虹殑宸ヤ綔鑰呯嚎紼嬫暟閲忚秴鍑簄涓紝閭d箞鍦ㄥ悓涓鏃跺埢錛屾渶澶氬彧鍏佽n涓嚎紼嬭繍琛屻備絾瀹為檯涓婏紝鍦ㄤ竴孌佃緝鐭殑鏃墮棿鍐咃紝緋葷粺鏈夊彲鑳借秴榪囪繖涓鹼紝浣嗗緢蹇究浼氭妸瀹冨噺灝戣嚦浜嬪厛鍦–reateIoCompletionPort鍑芥暟涓瀹氱殑鍊箋傞偅涔堬紝涓轟綍瀹為檯鍒涘緩鐨勫伐浣滆呯嚎紼嬫暟閲忔湁鏃惰姣擟reateIoCompletionPort鍑芥暟璁懼畾鐨勫涓浜涘憿錛熻繖鏍峰仛鏈夊繀瑕佸悧錛熷鍏堝墠鎵榪幫紝榪欎富瑕佸彇鍐充簬
搴旂敤紼嬪簭鐨勬諱綋璁捐鎯呭喌銆傚亣瀹氭垜浠殑鏌愪釜宸ヤ綔鑰呯嚎紼嬭皟鐢ㄤ簡涓涓嚱鏁幫紝姣斿Sleep鎴朩aitForSingleObject錛屼絾鍗磋繘鍏ヤ簡鏆傚仠錛堥攣瀹氭垨鎸傝搗錛夌姸鎬侊紝閭d箞鍏佽鍙︿竴涓嚎紼嬩唬鏇垮畠鐨勪綅緗傛崲璦涔嬶紝鎴戜滑甯屾湜闅忔椂閮借兘鎵ц灝藉彲鑳藉鐨勭嚎紼嬶紱褰撶劧錛屾渶澶х殑綰跨▼鏁伴噺鏄簨鍏堝湪CreateIoCompletionPort璋冪敤閲岃瀹氬ソ鐨勩傝繖鏍蜂竴鏉ワ紝鍋囧浜嬪厛棰勮鍒拌嚜宸辯殑綰跨▼鏈夊彲鑳芥殏鏃跺浜庡仠欏跨姸鎬侊紝閭d箞鏈濂借兘澶熷垱寤烘瘮CreateIoCompletionPort鐨凬umberOfConcurrentThreads鍙傛暟鐨勫煎鐨勭嚎紼嬶紝浠ヤ究鍒版椂鍊欏厖鍒嗗彂鎸ョ郴緇熺殑娼滃姏銆備竴鏃﹀湪瀹屾垚绔彛涓婃嫢鏈夎凍澶熷鐨勫伐浣滆呯嚎紼嬫潵涓篒/O璇鋒眰鎻愪緵鏈嶅姟錛屼究鍙潃鎵嬪皢濂楁帴瀛楀彞鏌勫悓瀹屾垚绔彛鍏寵仈鍒頒竴璧楓傝繖瑕佹眰鎴戜滑鍦ㄤ竴涓幇鏈夌殑瀹屾垚绔彛涓婏紝璋冪敤CreateIoCompletionPort鍑芥暟錛屽悓鏃朵負鍓嶄笁涓弬鏁扳斺擣ileHandle錛孍xistingCompletionPort鍜孋ompletionKey鈥斺旀彁渚涘鎺ュ瓧鐨勪俊鎭傚叾涓紝 FileHandle鍙傛暟鎸囧畾涓涓鍚屽畬鎴愮鍙e叧鑱斿湪涓璧風殑濂楁帴瀛楀彞鏌勩侲xistingCompletionPort鍙傛暟鎸囧畾鐨勬槸涓涓幇鏈夌殑瀹屾垚绔彛銆侰ompletionKey錛堝畬鎴愰敭錛夊弬鏁板垯鎸囧畾瑕佷笌鏌愪釜鐗瑰畾濂楁帴瀛楀彞鏌勫叧鑱斿湪涓璧風殑鈥滃崟鍙ユ焺鏁版嵁鈥濓紱鍦ㄨ繖涓弬鏁頒腑錛屽簲鐢ㄧ▼搴忓彲淇濆瓨涓庝竴涓鎺ュ瓧瀵瑰簲鐨勪換鎰忕被鍨嬬殑淇℃伅銆備箣鎵浠ユ妸瀹冨彨浣溾滃崟鍙ユ焺鏁版嵁鈥濓紝鏄敱浜庡畠鍙
搴旂潃涓庨偅涓鎺ュ瓧鍙ユ焺鍏寵仈鍦ㄤ竴璧風殑鏁版嵁銆傚彲灝嗗叾浣滀負鎸囧悜涓涓暟鎹粨鏋勭殑鎸囬拡錛屾潵淇濆瓨濂楁帴瀛楀彞鏌勶紱鍦ㄩ偅涓粨鏋勪腑錛屽悓鏃跺寘鍚簡濂楁帴瀛楃殑鍙ユ焺錛屼互鍙婁笌閭d釜濂楁帴瀛楁湁鍏崇殑鍏朵粬淇℃伅銆?/p>
鏍規嵁鎴戜滑鍒扮洰鍓嶄負姝㈠鍒扮殑涓滆タ錛岄鍏堟潵鏋勫緩涓涓熀鏈殑搴旂敤紼嬪簭妗嗘灦銆備笅闈㈤槓榪頒簡濡備綍浣跨敤瀹屾垚绔彛妯″瀷錛屾潵寮鍙戜竴涓狤CHO鏈嶅姟鍣ㄥ簲鐢ㄣ傚湪榪欎釜紼嬪簭涓紝鎴戜滑鍩烘湰涓婃寜涓嬭堪姝ラ琛屼簨錛?/p>
1) 鍒涘緩涓涓畬鎴愮鍙c傜鍥涗釜鍙傛暟淇濇寔涓?錛屾寚瀹氬湪瀹屾垚绔彛涓婏紝姣忎釜澶勭悊鍣ㄤ竴嬈″彧鍏佽鎵ц涓涓伐浣滆呯嚎紼嬨?br />2) 鍒ゆ柇緋葷粺鍐呭埌搴曞畨瑁呬簡澶氬皯涓鐞嗗櫒銆?br />3) 鍒涘緩宸ヤ綔鑰呯嚎紼嬶紝鏍規嵁姝ラ2)寰楀埌鐨勫鐞嗗櫒淇℃伅錛屽湪瀹屾垚绔彛涓婏紝涓哄凡瀹屾垚鐨処/O璇鋒眰鎻愪緵鏈嶅姟銆?br />4) 鍑嗗濂戒竴涓洃鍚鎺ュ瓧錛屽湪绔彛5150涓婄洃鍚繘鍏ョ殑榪炴帴璇鋒眰銆?br />5) 浣跨敤accept鍑芥暟錛屾帴鍙楄繘鍏ョ殑榪炴帴璇鋒眰銆?br />6) 鍒涘緩涓涓暟鎹粨鏋勶紝鐢ㄤ簬瀹圭撼鈥滃崟鍙ユ焺鏁版嵁鈥濓紝鍚屾椂鍦ㄧ粨鏋勪腑瀛樺叆鎺ュ彈鐨勫鎺ュ瓧鍙ユ焺銆?br />7) 璋冪敤CreateIoCompletionPort錛屽皢鑷猘ccept榪斿洖鐨勬柊濂楁帴瀛楀彞鏌勫悓瀹屾垚绔彛鍏寵仈鍒頒竴璧楓傞氳繃瀹屾垚閿紙CompletionKey錛夊弬鏁幫紝灝嗗崟鍙ユ焺鏁版嵁緇撴瀯浼犻掔粰CreateIoCompletionPort銆?br />8) 寮濮嬪湪宸叉帴鍙楃殑榪炴帴涓婅繘琛孖/O鎿嶄綔銆傚湪姝わ紝鎴戜滑甯屾湜閫氳繃閲嶅彔I/O鏈哄埗錛屽湪鏂板緩鐨勫鎺ュ瓧涓婃姇閫掍竴涓垨澶氫釜寮傛WSARecv鎴朩SASend璇鋒眰銆傝繖浜汭/O璇鋒眰瀹屾垚鍚庯紝涓涓伐浣滆呯嚎紼嬩細涓篒/O璇鋒眰鎻愪緵鏈嶅姟錛屽悓鏃剁戶緇鐞嗘湭鏉ョ殑I/O璇鋒眰錛岀◢鍚庝究浼氬湪姝ラ3 )鎸囧畾鐨勫伐浣滆呬緥紼嬩腑錛屼綋楠屽埌榪欎竴鐐廣?br />9) 閲嶅姝ラ5 ) ~ 8 )錛岀洿鑷蟲湇鍔″櫒涓銆?/p>
浜屻佸畬鎴愮鍙e拰閲嶅彔I/O
灝嗗鎺ュ瓧鍙ユ焺涓庝竴涓畬鎴愮鍙e叧鑱斿湪涓璧峰悗錛屼究鍙互濂楁帴瀛楀彞鏌勪負鍩虹錛屾姇閫掑彂閫佷笌鎺ユ敹璇鋒眰錛屽紑濮嬪I/O璇鋒眰鐨勫鐞嗐傛帴涓嬫潵錛屽彲寮濮嬩緷璧栧畬鎴愮鍙o紝鏉ユ帴鏀舵湁鍏矷/O鎿嶄綔瀹屾垚鎯呭喌鐨勯氱煡銆備粠鏈川涓婅錛屽畬鎴愮鍙fā鍨嬪埄鐢ㄤ簡Win32閲嶅彔I/O鏈哄埗銆傚湪榪欑鏈哄埗涓紝璞SASend鍜學SARecv榪欐牱鐨刉insock API璋冪敤浼氱珛鍗寵繑鍥炪傛鏃訛紝闇瑕佺敱鎴戜滑鐨勫簲鐢ㄧ▼搴忚礋璐e湪浠ュ悗鐨勬煇涓椂闂達紝閫氳繃涓涓狾VERLAPPED緇撴瀯錛屾潵鎺ユ敹璋冪敤鐨勭粨鏋溿傚湪瀹屾垚绔彛妯″瀷涓紝瑕佹兂鍋氬埌榪欎竴鐐癸紝闇瑕佷嬌鐢℅etQueuedCompletionStatus錛堣幏鍙栨帓闃熷畬鎴愮姸鎬侊級鍑芥暟錛岃涓涓垨澶氫釜宸ヤ綔鑰呯嚎紼嬪湪瀹屾垚绔彛涓婄瓑寰呫傝鍑芥暟鐨勫畾涔夊涓嬶細
BOOL GetQueuedCompletionStatus(
聽聽聽 HANDLE CompletionPort,
聽聽聽 LPDWORD lpNumberOfBytes,
聽聽聽 PULONG_PTR lpCompletionKey,
聽聽聽 LPOVERLAPPED* lpOverlapped,
聽聽聽 DWORD dwMilliseconds
);
鍏朵腑錛孋ompletionPort鍙傛暟瀵瑰簲浜庤鍦ㄤ笂闈㈢瓑寰呯殑瀹屾垚绔彛銆俵pNumberOfBytes鍙傛暟璐熻矗鍦ㄥ畬鎴愪簡涓嬈/O鎿嶄綔鍚庯紙濡俉SASend鎴朩SARecv錛夛紝鎺ユ敹瀹為檯浼犺緭鐨勫瓧鑺傛暟銆俵pCompletionKey鍙傛暟涓哄師鍏堜紶閫掕繘鍏reateIoCompletionPort鍑芥暟鐨勫鎺ュ瓧榪斿洖鈥滃崟鍙ユ焺鏁版嵁鈥濄傚鎴戜滑鏃╁厛鎵榪幫紝澶у鏈濂藉皢濂楁帴瀛楀彞鏌勪繚瀛樺湪榪欎釜鈥滈敭鈥濓紙Key錛変腑銆俵pOverlapped鍙傛暟鐢ㄤ簬鎺ユ敹瀹屾垚鐨処/O鎿嶄綔鐨勯噸鍙犵粨鏋溿傝繖瀹為檯鏄竴涓浉褰撻噸瑕佺殑鍙傛暟錛屽洜涓哄彲鐢ㄥ畠鑾峰彇姣忎釜I/O鎿嶄綔鐨勬暟鎹傝屾渶鍚庝竴涓弬鏁幫紝dwMilliseconds錛岀敤浜庢寚瀹氳皟鐢ㄨ呭笇鏈涚瓑寰呬竴涓畬鎴愭暟鎹寘鍦ㄥ畬鎴愮鍙d笂鍑虹幇鐨勬椂闂淬傚亣濡傚皢鍏惰涓篒NFINITE錛岃皟鐢ㄤ細鏃犱紤姝㈠湴絳夊緟涓嬪幓銆?
涓夈佸崟鍙ユ焺鏁版嵁鍜屽崟I/O鎿嶄綔鏁版嵁
涓涓伐浣滆呯嚎紼嬩粠GetQueuedCompletionStatus榪欎釜API璋冪敤鎺ユ敹鍒癐/O瀹屾垚閫氱煡鍚庯紝鍦╨pCompletionKey鍜宭pOverlapped鍙傛暟涓紝浼氬寘鍚竴浜涘繀瑕佺殑濂楁帴瀛椾俊鎭傚埄鐢ㄨ繖浜涗俊鎭紝鍙氳繃瀹屾垚绔彛錛岀戶緇湪涓涓鎺ュ瓧涓婄殑I/O澶勭悊銆傞氳繃榪欎簺鍙傛暟錛屽彲鑾峰緱涓ゆ柟闈㈤噸瑕佺殑濂楁帴瀛楁暟鎹細鍗曞彞鏌勬暟鎹紝浠ュ強鍗旾/O鎿嶄綔鏁版嵁銆傚叾涓紝lpCompletionKey鍙傛暟鍖呭惈浜嗏滃崟鍙ユ焺鏁版嵁鈥濓紝鍥犱負鍦ㄤ竴涓鎺ュ瓧棣栨涓庡畬鎴愮鍙e叧鑱斿埌涓璧風殑鏃跺欙紝閭d簺鏁版嵁渚夸笌涓涓壒瀹氱殑濂楁帴瀛楀彞鏌勫搴旇搗鏉ヤ簡銆傝繖浜涙暟鎹鏄垜浠湪榪涜CreateIoCompletionPort API璋冪敤鐨勬椂鍊欙紝閫氳繃CompletionKey鍙傛暟浼犻掔殑銆傚鏃╁厛鎵榪幫紝搴旂敤紼嬪簭鍙氳繃璇ュ弬鏁頒紶閫掍換鎰忕被鍨嬬殑鏁版嵁銆傞氬父鎯呭喌涓嬶紝搴旂敤紼嬪簭浼氬皢涓嶪/O璇鋒眰鏈夊叧鐨勫鎺ュ瓧鍙ユ焺淇濆瓨鍦ㄨ繖閲屻俵pOverlapped鍙傛暟鍒欏寘鍚簡涓涓狾VERLAPPED緇撴瀯錛屽湪瀹冨悗闈㈣窡闅忊滃崟I/O鎿嶄綔鏁版嵁鈥濄傛垜浠殑宸ヤ綔鑰呯嚎紼嬪鐞嗕竴涓畬鎴愭暟鎹寘鏃訛紙灝嗘暟鎹師灝佷笉鍔ㄦ墦杞洖鍘伙紝鎺ュ彈榪炴帴錛屾姇閫掑彟涓涓嚎紼嬶紝絳夌瓑錛夛紝榪欎簺淇℃伅鏄畠蹇呴』瑕佺煡閬撶殑銆傚崟I/O鎿嶄綔鏁版嵁鍙互鏄拷鍔犲埌涓涓狾VERLAPPED緇撴瀯鏈熬鐨勩佷換鎰忔暟閲忕殑瀛楄妭銆傚亣濡備竴涓嚱鏁拌姹傜敤鍒頒竴涓狾VERLAPPED緇撴瀯錛屾垜浠究蹇呴』灝嗚繖鏍風殑涓涓粨鏋勪紶閫掕繘鍘伙紝浠ユ弧瓚沖畠鐨勮姹傘傝鎯沖仛鍒拌繖涓鐐癸紝涓涓畝鍗曠殑鏂規硶鏄畾涔変竴涓粨鏋勶紝鐒跺悗灝哋VERLAPPED緇撴瀯浣滀負鏂扮粨鏋勭殑絎竴涓厓绱犱嬌鐢ㄣ備婦涓緥瀛愭潵璇達紝鍙畾涔変笅榪版暟鎹粨鏋勶紝瀹炵幇瀵瑰崟I/O鎿嶄綔鏁版嵁鐨勭鐞嗭細
typedef struct
{
聽聽聽 OVERLAPPED Overlapped;
聽聽聽 WSABUF聽聽聽聽 DataBuf;
聽聽聽 CHAR聽聽聽聽聽聽 Buffer[DATA_BUFSIZE];
聽聽聽 BOOL聽聽聽聽聽聽 OperationType;
}PER_IO_OPERATION_DATA
璇ョ粨鏋勬紨紺轟簡閫氬父瑕佷笌I/O鎿嶄綔鍏寵仈鍦ㄤ竴璧風殑鏌愪簺閲嶈鏁版嵁鍏冪礌錛屾瘮濡傚垰鎵嶅畬鎴愮殑閭d釜I/O鎿嶄綔鐨勭被鍨嬶紙鍙戦佹垨鎺ユ敹璇鋒眰錛夈傚湪榪欎釜緇撴瀯涓紝鎴戜滑璁や負鐢ㄤ簬宸插畬鎴怚/O鎿嶄綔鐨勬暟鎹紦鍐插尯鏄潪甯告湁鐢ㄧ殑銆傝鎯寵皟鐢ㄤ竴涓猈insock API鍑芥暟錛屽悓鏃朵負鍏跺垎閰嶄竴涓狾VERLAPPED緇撴瀯錛屾棦鍙皢鑷繁鐨勭粨鏋勨滈犲瀷鈥濅負涓涓狾VERLAPPED鎸囬拡錛屼害鍙畝鍗曞湴鎾ゆ秷瀵圭粨鏋勪腑鐨凮VERLAPPED鍏冪礌鐨勫紩鐢ㄣ傚涓嬩緥鎵紺猴細
PER_IO_OPERATION_DATA PerIoData;
// 鍙儚涓嬮潰榪欐牱璋冪敤涓涓嚱鏁?br />聽 WSARecv(socket, ..., (OVERLAPPED *)&PerIoData);
// 鎴栧儚榪欐牱
聽 WSARecv(socket, ..., &(PerIoData.Overlapped));
鍦ㄥ伐浣滅嚎紼嬬殑鍚庨潰閮ㄥ垎錛岀瓑GetQueuedCompletionStatus鍑芥暟榪斿洖浜嗕竴涓噸鍙犵粨鏋勶紙鍜屽畬鎴愰敭錛夊悗錛屼究鍙氳繃鎾ゆ秷瀵筄perationType鎴愬憳鐨勫紩鐢紝璋冩煡鍒板簳鏄摢涓搷浣滄姇閫掑埌浜嗚繖涓彞鏌勪箣涓婏紙鍙渶灝嗚繑鍥炵殑閲嶅彔緇撴瀯閫犲瀷涓鴻嚜宸辯殑PER_IO_OPERATION_DATA緇撴瀯錛夈傚鍗旾/O鎿嶄綔鏁版嵁鏉ヨ錛屽畠鏈澶х殑涓涓紭鐐逛究鏄厑璁告垜浠湪鍚屼竴涓彞鏌勪笂錛屽悓鏃剁鐞嗗涓狪/O鎿嶄綔錛堣/鍐欙紝澶氫釜璇伙紝澶氫釜鍐欙紝絳夌瓑錛夈傚ぇ瀹舵鏃舵垨璁鎬細浜х敓榪欐牱鐨勭枒闂細鍦ㄥ悓涓涓鎺ュ瓧涓婏紝鐪熺殑鏈夊繀瑕佸悓鏃舵姇閫掑涓狪/O鎿嶄綔鍚楋紵絳旀鍦ㄤ簬緋葷粺鐨勨滀幾緙╂р濓紝鎴栬呰鈥滄墿灞曡兘鍔涒濄備緥濡傦紝鍋囧畾鎴戜滑鐨勬満鍣ㄥ畨瑁呬簡澶氫釜涓ぎ澶勭悊鍣紝姣忎釜澶勭悊鍣ㄩ兘鍦ㄨ繍琛屼竴涓伐浣滆呯嚎紼嬶紝閭d箞鍦ㄥ悓涓涓椂
鍊欙紝瀹屽叏鍙兘鏈夊嚑涓笉鍚岀殑澶勭悊鍣ㄥ湪鍚屼竴涓鎺ュ瓧涓婏紝榪涜鏁版嵁鐨勬敹鍙戞搷浣溿?
鏈鍚庤娉ㄦ剰鐨勪竴澶勭粏鑺傛槸濡備綍姝g‘鍦板叧闂璉/O瀹屾垚绔彛鈥旂壒鍒槸鍚屾椂榪愯浜嗕竴涓垨澶氫釜綰跨▼錛屽湪鍑犱釜涓嶅悓鐨勫鎺ュ瓧涓婃墽琛孖/O鎿嶄綔鐨勬椂鍊欍傝閬垮厤鐨勪竴涓噸瑕侀棶棰樻槸鍦ㄨ繘琛岄噸鍙營/O鎿嶄綔鐨勫悓鏃訛紝寮鴻閲婃斁涓涓狾VERLAPPED緇撴瀯銆傝鎯抽伩鍏嶅嚭鐜拌繖縐嶆儏鍐碉紝鏈濂界殑鍔炴硶鏄拡瀵規瘡涓鎺ュ瓧鍙ユ焺錛岃皟鐢╟losesocket鍑芥暟錛屼換浣曞皻鏈繘琛岀殑閲嶅彔I/O鎿嶄綔閮戒細瀹屾垚銆備竴鏃︽墍鏈夊鎺ュ瓧鍙ユ焺閮藉凡鍏抽棴錛屼究闇鍦ㄥ畬鎴愮鍙d笂錛岀粓姝㈡墍鏈夊伐浣滆呯嚎紼嬬殑榪愯銆傝鎯沖仛鍒拌繖涓鐐癸紝 闇瑕佷嬌鐢≒ostQueuedCompletionStatus鍑芥暟錛屽悜姣忎釜宸ヤ綔鑰呯嚎紼嬮兘鍙戦佷竴涓壒孌婄殑瀹屾垚鏁版嵁鍖呫傝鍑芥暟浼氭寚紺烘瘡涓嚎紼嬮兘鈥滅珛鍗崇粨鏉熷茍閫鍑衡濄備笅闈㈡槸PostQueuedCompletionStatus鍑芥暟鐨勫畾涔夛細
BOOL PostQueuedCompletionStatus(
聽聽聽 HANDLE CompletionPort,
聽聽聽 DWORD dwNumberOfBytesTransferred,
聽聽聽 ULONG_PTR dwCompletionKey,
聽聽聽 LPOVERLAPPED lpOverlapped
);
鍏朵腑錛孋ompletionPort鍙傛暟鎸囧畾鎯沖悜鍏跺彂閫佷竴涓畬鎴愭暟鎹寘鐨勫畬鎴愮鍙e璞°傝屽氨dwNumberOfBytesTransferred銆乨wCompletionKey鍜宭pOverlapped榪欎笁涓弬鏁版潵璇達紝姣忎竴涓兘鍏佽鎴戜滑鎸囧畾涓涓鹼紝鐩存帴浼犻掔粰GetQueuedCompletionStatus鍑芥暟涓搴旂殑鍙傛暟銆傝繖鏍蜂竴鏉ワ紝涓涓伐浣滆呯嚎紼嬫敹鍒頒紶閫掕繃鏉ョ殑涓変釜GetQueuedCompletionStatus鍑芥暟鍙傛暟鍚庯紝渚垮彲鏍規嵁鐢辮繖涓変釜鍙傛暟鐨勬煇涓涓緗殑鐗規畩鍊鹼紝鍐沖畾浣曟椂搴旇閫鍑恒備緥濡傦紝鍙敤dwCompletionPort鍙傛暟浼犻?鍊鹼紝鑰屼竴涓伐浣滆呯嚎紼嬩細灝嗗叾瑙i噴鎴愪腑姝㈡寚浠ゃ備竴鏃︽墍鏈夊伐浣滆呯嚎紼嬮兘宸插叧闂紝渚垮彲浣跨敤CloseHandle鍑芥暟錛屽叧闂畬鎴愮鍙o紝鏈緇堝畨鍏ㄩ鍑虹▼搴忋?/p>
娉細CreateIoCompletionPort 錛孭ostQueuedCompletionStatus 錛孏etQueuedCompletionStatus 絳夊嚱鏁扮殑鐢ㄦ硶璇存槑銆?/p>
Platform SDK: Storage
聽
聽
I/O Completion Ports
I/O completion ports are the mechanism by which an application uses a pool of threads that was created when the application was started to process asynchronous I/O requests. These threads are created for the sole purpose of processing I/O requests. Applications that process many concurrent asynchronous I/O requests can do so more quickly and efficiently by using I/O completion ports than by using creating threads at the time of the I/O request.
聽
聽
聽
聽
聽
I/O瀹屾垚绔彛(s)鏄竴縐嶆満鍒訛紝閫氳繃榪欎釜鏈哄埗錛屽簲鐢ㄧ▼搴忓湪鍚姩鏃朵細棣栧厛鍒涘緩涓涓嚎紼嬫睜錛岀劧鍚庤搴旂敤紼嬪簭浣跨敤綰跨▼姹犲鐞嗗紓姝/O璇鋒眰銆傝繖浜涚嚎紼嬭鍒涘緩鐨勫敮涓鐩殑灝辨槸鐢ㄤ簬澶勭悊I/O璇鋒眰銆傚浜庡鐞嗗ぇ閲忓茍鍙戝紓姝/O璇鋒眰鐨勫簲鐢ㄧ▼搴忔潵璇達紝鐩告瘮浜庡湪I/O璇鋒眰鍙戠敓鏃跺垱寤虹嚎紼嬫潵璇達紝浣跨敤瀹屾垚绔彛(s)瀹冨氨鍙互鍋氱殑鏇村揩涓旀洿鏈夋晥鐜囥?
聽
聽
聽
聽
聽
The CreateIoCompletionPort function associates an I/O completion port with one or more file handles. When an asynchronous I/O operation started on a file handle associated with a completion port is completed, an I/O completion packet is queued to the port. This can be used to combine the synchronization point for multiple file handles into a single object.
聽
聽
聽
聽
聽
CreateIoCompletionPort鍑芥暟浼氫嬌涓涓狪/O瀹屾垚绔彛涓庝竴涓垨澶氫釜鏂囦歡鍙ユ焺鍙戠敓鍏寵仈銆傚綋涓庝竴涓畬鎴愮鍙g浉鍏崇殑鏂囦歡鍙ユ焺涓婂惎鍔ㄧ殑寮傛I/O鎿嶄綔瀹屾垚鏃訛紝涓涓狪/O瀹屾垚鍖呭氨浼氳繘鍏ュ埌璇ュ畬鎴愮鍙g殑闃熷垪涓傚浜庡涓枃浠跺彞鏌勬潵璇達紝灝卞彲浠ユ妸榪欎簺澶氫釜鏂囦歡鍙ユ焺鍚堝茍鎴愪竴涓崟鐙殑瀵硅薄錛岃繖涓彲浠ヨ鐢ㄦ潵緇撳悎鍚屾鐐癸紵
聽
聽
聽
聽
聽
A thread uses the GetQueuedCompletionStatus function to wait for a completion packet to be queued to the completion port, rather than waiting directly for the asynchronous I/O to complete. Threads that block their execution on a completion port are released in last-in-first-out (LIFO) order. This means that when a completion packet is queued to the completion port, the system releases the last thread to block its execution on the port.
聽
聽
璋冪敤GetQueuedCompletionStatus鍑芥暟錛屾煇涓嚎紼嬪氨浼氱瓑寰呬竴涓畬鎴愬寘榪涘叆鍒板畬鎴愮鍙g殑闃熷垪涓紝鑰屼笉鏄洿鎺ョ瓑寰呭紓姝/O璇鋒眰瀹屾垚銆傜嚎紼嬶紙浠級灝變細闃誨浜庡畠浠殑榪愯鍦ㄥ畬鎴愮鍙o紙鎸夌収鍚庤繘鍏堝嚭闃熷垪欏哄簭鐨勮閲婃斁錛夈傝繖灝辨剰鍛崇潃褰撲竴涓畬鎴愬寘榪涘叆鍒板畬鎴愮鍙g殑闃熷垪涓椂錛岀郴緇熶細閲婃斁鏈榪戣闃誨鍦ㄨ瀹屾垚绔彛鐨勭嚎紼嬨?
聽
聽
聽
聽
聽
When a thread calls GetQueuedCompletionStatus, it is associated with the specified completion port until it exits, specifies a different completion port, or frees the completion port. A thread can be associated with at most one completion port.
聽
聽
璋冪敤GetQueuedCompletionStatus錛岀嚎紼嬪氨浼氬皢浼氫笌鏌愪釜鎸囧畾鐨勫畬鎴愮鍙e緩绔嬭仈緋伙紝涓鐩村歡緇叾璇ョ嚎紼嬬殑瀛樺湪鍛ㄦ湡錛屾垨琚寚瀹氫簡涓嶅悓鐨勫畬鎴愮鍙o紝鎴栬呴噴鏀句簡涓庡畬鎴愮鍙g殑鑱旂郴銆備竴涓嚎紼嬪彧鑳戒笌鏈澶氫笉瓚呰繃涓涓殑瀹屾垚绔彛鍙戠敓鑱旂郴銆?
聽
聽
聽
聽
聽
The most important property of a completion port is the concurrency value. The concurrency value of a completion port is specified when the completion port is created. This value limits the number of runnable threads associated with the completion port. When the total number of runnable threads associated with the completion port reaches the concurrency value, the system blocks the execution of any subsequent threads that specify the completion port until the number of runnable threads associated with the completion port drops below the concurrency value. The most efficient scenario occurs when there are completion packets waiting in the queue, but no waits can be satisfied because the port has reached its concurrency limit. In this case, when a running thread calls GetQueuedCompletionStatus, it will immediately pick up the queued completion packet. No context switches will occur, because the running thread is continually picking up completion packets and the other threads are unable to run.
聽
聽
瀹屾垚绔彛鏈閲嶈鐨勭壒鎬у氨鏄茍鍙戦噺銆傚畬鎴愮鍙g殑騫跺彂閲忓彲浠ュ湪鍒涘緩璇ュ畬鎴愮鍙f椂鎸囧畾銆傝騫跺彂閲忛檺鍒朵簡涓庤瀹屾垚绔彛鐩稿叧鑱旂殑鍙繍琛岀嚎紼嬬殑鏁扮洰銆傚綋涓庤瀹屾垚绔彛鐩稿叧鑱旂殑鍙繍琛岀嚎紼嬬殑鎬繪暟鐩揪鍒頒簡璇ュ茍鍙戦噺錛岀郴緇熷氨浼氶樆濉炰換浣曚笌璇ュ畬鎴愮鍙g浉鍏寵仈鐨勫悗緇嚎紼嬬殑鎵ц錛岀洿鍒頒笌璇ュ畬鎴愮鍙g浉鍏寵仈鐨勫彲榪愯綰跨▼鏁扮洰涓嬮檷鍒板皬浜庤騫跺彂閲忎負姝€傛渶鏈夋晥鐨勫亣鎯蟲槸鍙戠敓鍦ㄦ湁瀹屾垚鍖呭湪闃熷垪涓瓑寰咃紝鑰屾病鏈夌瓑寰呰婊¤凍錛屽洜涓烘鏃跺畬鎴愮鍙h揪鍒頒簡鍏跺茍鍙戦噺鐨勬瀬闄愩傛鏃訛紝涓涓鍦ㄨ繍琛屼腑鐨勭嚎紼嬭皟鐢℅etQueuedCompletionStatus鏃訛紝瀹冨氨浼氱珛鍒諱粠闃熷垪涓彇璧拌瀹屾垚鍖呫傝繖鏍峰氨涓嶅瓨鍦ㄧ潃鐜鐨勫垏鎹紝鍥犱負璇ュ浜庤繍琛屼腑鐨勭嚎紼嬪氨浼氳繛緇笉鏂湴浠庨槦鍒椾腑鍙栬蛋瀹屾垚鍖咃紝鑰屽叾浠栫殑綰跨▼灝變笉鑳借繍琛屼簡銆?
聽
聽
聽
聽
聽
The best value to pick for the concurrency value is the number of CPUs on the machine. If your transaction required a lengthy computation, a larger concurrency value will allow more threads to run. Each transaction will take longer to complete, but more transactions will be processed at the same time. It is easy to experiment with the concurrency value to achieve the best effect for your application.
聽
聽
瀵逛簬騫跺彂閲忔渶濂界殑鎸戦夊煎氨鏄偍璁$畻鏈轟腑cpu鐨勬暟鐩傚鏋滄偍鐨勪簨鍔″鐞嗛渶瑕佷竴涓極闀跨殑璁$畻鏃墮棿錛屼竴涓瘮杈冨ぇ鐨勫茍鍙戦噺鍙互鍏佽鏇村綰跨▼鏉ヨ繍琛屻傝櫧鐒跺畬鎴愭瘡涓簨鍔″鐞嗛渶瑕佽姳璐規洿闀跨殑鏃墮棿錛屼絾鏇村鐨勪簨鍔″彲浠ュ悓鏃惰澶勭悊銆傚浜庡簲鐢ㄧ▼搴忔潵璇達紝寰堝鏄撻氳繃嫻嬭瘯騫跺彂閲忔潵鑾峰緱鏈濂界殑鏁堟灉銆?
聽
聽
聽
聽
聽
The PostQueuedCompletionStatus function allows an application to queue its own special-purpose I/O completion packets to the completion port without starting an asynchronous I/O operation. This is useful for notifying worker threads of external events.
聽
聽
PostQueuedCompletionStatus鍑芥暟鍏佽搴旂敤紼嬪簭鍙互閽堝鑷畾涔夌殑涓撶敤I/O瀹屾垚鍖呰繘琛屾帓闃燂紝鑰屾棤闇鍚姩涓涓紓姝/O鎿嶄綔銆傝繖鐐瑰浜庨氱煡澶栭儴浜嬩歡鐨勫伐浣滆呯嚎紼嬫潵璇村緢鏈夌敤銆?
聽
聽
聽
聽
聽
The completion port is freed when there are no more references to it. The completion port handle and every file handle associated with the completion port reference the completion port. All the handles must be closed to free the completion port. To close the port handle, call the CloseHandle function.
聽
聽
鍦ㄦ病鏈夋洿澶氱殑寮曠敤閽堝鏌愪釜瀹屾垚绔彛鏃訛紝闇瑕侀噴鏀捐瀹屾垚绔彛銆傝瀹屾垚绔彛鍙ユ焺浠ュ強涓庤瀹屾垚绔彛鐩稿叧鑱旂殑鎵鏈夋枃浠跺彞鏌勯兘闇瑕佽閲婃斁銆傝皟鐢–loseHandle鍙互閲婃斁瀹屾垚绔彛鐨勫彞鏌勩?