之前一直接從事企業管理的軟件,接觸網絡比較少。網絡方面的知識也很慘。
最近想弄下iocp。網上找了很多資料,大部分是關於c++的。delphi的比較少。
看了下,不適合剛接觸網絡的菜鳥學習!
看過fxh的blog,覺得寫的容易理解。
http://fxh7622.blog.51cto.com/63841/7667
基本上按照他的blog代碼進行的編寫。編譯理解iocp的原理。
首先我來個通俗的理解步驟。
1.服務器創建一個iocp端口服務。
2.服務器創建N個工作線程,不停的輪流處理這個端口上面的連接和請求。
3.開啟iocp的端口服務<綁定監聽端口,進行監聽>。如果接收到請求,通知iocp工作線程。
*剛開始看人家代碼的時候,一直想為什么是先創建工作線程,而不是先開啟端口服務。
<我是這樣理解的>如果先開啟端口服務,如果這個時候有連接,工作線程還沒有准備就緒,那就會錯過請求。
好下面開始分析代碼<盡量去掉了其他代碼,這樣更看的清楚>
1: var
2: WSData: TWSAData;
3: lvIOPort:THandle;
4: hThread, dwThreadId:DWORD;
5:
6: sSocket, cSocket:TSocket;
7: lvAddr:TSockAddr;
8: lvAddrSize:Integer;
9: lvMsg:String;
10: lvPort:Integer;
11:
12: lvSystemInfo: TSystemInfo;
13: i:Integer;
14: lvCount:Integer;
15: begin
16:
17: lvPort := 8988;
18:
19: //加載SOCKET。使用的是2.2版為了后面方便加入心跳。
20: WSAStartup($0202, WSData);
21:
22: // 創建一個完成端口(內核對象)
23: lvIOPort := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
24:
25:
26: //獲取系統信息<cpu的數量>
27: // GetSystemInfo(lvSystemInfo);
28: //lvCount := lvSystemInfo.dwNumberOfProcessors * 2 -1;
29:
30: //便於調試先創建一個工作線程
31: lvCount := 1;
32:
33: for I:=0 to lvCount do
34: begin
35: hThread := CreateThread(nil, 0, @ServerWorkerThread,
36: Pointer(lvIOPort),0, dwThreadId);
37: if (hThread = 0) then
38: begin
39: Exit;
40: end;
41: CloseHandle(hThread);
42: end;
43:
44:
45: //創建一個套接字,將此套接字和一個端口綁定並監聽此端口。
46: sSocket:=WSASocket(AF_INET,SOCK_STREAM,0,Nil,0,WSA_FLAG_OVERLAPPED);
47: if sSocket=SOCKET_ERROR then
48: begin
49: closesocket(sSocket);
50: WSACleanup();
51: end;
52: lvAddr.sin_family:=AF_INET;
53: lvAddr.sin_port:=htons(lvPort);
54: lvAddr.sin_addr.s_addr:=htonl(INADDR_ANY);
55: if bind(sSocket,@lvAddr,sizeof(lvAddr))=SOCKET_ERROR then
56: begin
57: closesocket(sSocket);
58: end;
59:
60: listen(sSocket,20);
其中ServerWorkerThread是工作的函數,用線程的方式方式運行。
//下一篇分析下監聽工作。