今天简单实践了最基本的 IOCP http server , 原则上是用我第二天写的 one2Many httpServer 改的。
中间会撷取跟 IOCP 有关的部分讲讲。
其实我不觉得大家有必要深入的去读原始码, 因为真的有点复杂, 会了也没太大作用, 我想, 只要稍微看过我写的概念, 心中大概有些认知, 之後读 node 的原始码时应该就够用了。
https://gist.github.com/leon123858/29ecce37aa3c43c59b8362cd336c75ef
以下会用 3 个步骤来解释 IOCP 在这个 http server 中的意义
httpServer() {
// 上略, 仅创建 TCP 连线 socket
// 创建 IOCP 公用 queue
eventQueue = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
if (eventQueue == NULL)
errorHandle("IOCP create");
// 将 TCP 连线事件注册进 IOCP, 等待客户端连线的事件发生
if (CreateIoCompletionPort((HANDLE)listenSocket, eventQueue, (ULONG_PTR)0, 0) == NULL)
errorHandle("IOCP listen");
// 创建沉睡的 threadpool 等待讯息传入的事件发生後醒来处理事件
for (int i = 0; i < THREADPOOL_SIZE; i++)
workerThreads[i] = thread(&httpServer::workerThreadFunction, this, eventQueue);
}
// 创建连线客户端 socket
struct sockaddr_in clientSocketSetting;
int clientSocketSettingLength;
clientSocketSettingLength = sizeof(clientSocketSetting);
SOCKET messageSocket = accept(listenSocket, (struct sockaddr*)&clientSocketSetting, &clientSocketSettingLength);
// 把连线客户端的 socket 注册进 IOCP , 所以等下 WSARecv 把客户端的讯息传入 queue 後, 也会触发事件。
ioInformation* ioInfo = new ioInformation(messageSocket);
if (CreateIoCompletionPort((HANDLE)messageSocket, eventQueue, (ULONG_PTR)ioInfo, 0) == NULL)
errorHandle("IOCP listen");
// 把客户端的讯息传入 queue , 传进去後会触发事件唤醒 threadpool 中的 thread。
WSARecv(messageSocket, &(ioInfo->wsaBuf),1, &recvBytes, &flags, &(ioInfo->overlapped), NULL);
while (true){
// IOCP 提供的方法, 使 thread 沉睡, 当 queue 中有一个事件, 就唤醒一条 thread, 且取出资料
result = GetQueuedCompletionStatus(eventQueue,&ipNumberOfBytes,(PULONG_PTR)&ipCompletionKey,&ipOverlap,INFINITE);
// 确认事件类型
if (result == 0 || ipNumberOfBytes == 0)
continue;
// http response
ioInformation* ioInfo = (ioInformation*)ipCompletionKey;
request req = request(ioInfo->wsaBuf.buf, ioInfo->wsaBuf.len);
if (req.requestType < 0) {
delete ioInfo;
continue;
}
cout << req.typeName[req.requestType] << " : " << req.filePath << endl;
int sentResult = responseClient(req, ioInfo->socket);
if (sentResult <= 0) {
printf("send error\n");
break;
}
delete ioInfo;
}
明天会开始探讨一个关於 node 的小实验。
明天见
<<: (Day17) this 介绍下 - 绑定 this 的 call & apply & bind 与严格模式
>>: [从0到1] C#小乳牛 练成基础程序逻辑 Day 2 - Visual Studio 2022 开发环境建立 64位元
我想要用这个工具来看SQL等等的debug讯息 但是我怎麽用他都不会出现那条展示列 如果有高手看到这...
实际操作 了解 requests 与 BeautifulSoup 的功能後,我们来进行整合吧!接下来...
前两天我们做了一个网页服务器,接下来我们来帮它加上 GUI 吧! Electron Electron...
今天讲二元树的删除,特别拉一篇出来讲,是因为它满复杂,要处理的case很多。 树的删除这边会把它分成...
为何 Azure CLI / SDK / Portal / PowerShell 的行为可以一致,背...