Previously, software directly engaged in enterprise management had less access to networks. Network knowledge is also miserable.
Recently I Want To Get iocp. I found a lot of information online, mostly about C ++. Delphi is rarely used.
After reading this, I am not familiar with cainiao learning!
I read fxh's blog and thought it was easy to understand.
Http://fxh7622.blog.51cto.com/63841/7667
Basically, it is written according to his blog code. Compile and understand iocp principles.
First, let's take a general understanding.
1. The server creates an iocp port service.
2. The server creates n working threads and continuously processes the connections and requests on the port in turn.
3. Enable the iocp port service <bind the listening port to listen>. If a request is received, the iocp working thread is notified.
* When I first looked at people's code, I always wondered why I first created a working thread instead of enabling the port service.
<I understand it like this> If you enable the port service first, if there is a connection at this time and the worker thread is not ready yet, the request will be missed.
Well, let's start analyzing the code. <try to get rid of other code to make it clearer.>
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: // load the socket. Version 2.2 is used to facilitate heartbeat.
20: WSAStartup($0202, WSData);
21:
22: // create a complete port (Kernel Object)
23: lvIOPort := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
24:
25:
26: // obtain System Information <Number of CPUs>
27: // GetSystemInfo(lvSystemInfo);
28: //lvCount := lvSystemInfo.dwNumberOfProcessors * 2 -1;
29:
30: // create a working thread for debugging
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: // create a socket, bind the socket to a port, and listen to the port.
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);
Specifically, serverworkerthread is a working function and runs in the thread mode.
// The next post analyzes the listener.