c++ - 同一容器中的 IOCP 多个套接字完成端口

标签 c++ windows io winsock iocp

在过去的几天里,我一直在思考如何解决我面临的一个问题,我也尝试研究这个主题,但我真的不知道我能做什么。

我在同一个结构中有 2 个套接字,它们都具有相同的完成端口。问题是,它们都使用不同的协议(protocol)。有没有办法找出触发了哪个套接字?他们叫game_socket,和client_socket

示例代码类似于...

while (true) {
error = GetQueuedCompletionStatus(CompletionPort, &BytesTransfered, (PULONG_PTR)&Key, &lpOverlapped, 0);
srvc = CONTAINING_RECORD ( lpOverlapped, client , ol );
if ( error == TRUE ) {
cout << endl << "SOCKET: [" << srvc->client_socket << "] TRIGGERED - WORKER THREAD" << endl;
cout << endl << "BytesTransfered: [" << BytesTransfered << "]" << endl;

if ( srvc->game_client triggered ) {
// .. this code
} else {

// .. this code
}

任何想法或帮助将不胜感激:)

最佳答案

当使用 IOCP 时,您可以在每个异步操作中使用两项用户数据。

第一个是完成键,它是“每个连接”数据,当您通过使用套接字/文件句柄和现有完成端口调用 CreateIoCompletionPort() 将文件句柄或套接字与完成端口相关联时设置。每次调用给定连接的 GetQueuedCompletionStatus() 时都会返回此值。

第二个是“扩展重叠”结构,它是“每个操作”数据。每个并发操作都必须为其分配一个唯一的重叠结构。

在您上面的设计中,您应该使用“每个连接”数据来识别您的连接。您有两个链接的连接(套接字),因此我将有两个链接类,一个用于连接的每一侧。该类(如果您使用的是 C 而不是 C++,则为结构)将保存套接字、指向连接另一半的指针和指示它是哪种连接类型的标志。如果使用 C++,这两个类将从公共(public)基类派生,以便您可以调用成员函数来确定完成键代表哪种类型的连接。如果使用 C,请使用可区分的 union 。

然后您只需将完成键转换为基类,然后确定您拥有的连接类型并转换为正确的类/结构。您现在知道操作是在哪个连接上执行的。连接类可以存储运行其协议(protocol)的状态机的所有状态。

正如 Criag 提到的,每个重叠结构都是“每个操作唯一的”,在我的 IOCP 代码中,这往往允许访问操作的数据缓冲区和一个告诉我操作是什么的标志(读/写/接受/连接等)。

一个潜在的复杂性是让每个操作和每个连接的数据保持事件状态,直到使用它的所有未完成的操作都完成。我个人更喜欢对每个连接和每个操作数据进行引用计数,但我相信还有其他方法。

我有一些使用这些概念的 IOCP 示例代码(尽管没有提供“双连接”示例),您可以从此处下载:http://www.serverframework.com/products---the-free-framework.html

关于c++ - 同一容器中的 IOCP 多个套接字完成端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12241690/

相关文章:

c++ - 从 OpenCL 内核修改 VBO 数据

c++ - 使用 StrTk String Toolkit Library 编写 CSV 的示例

c++ - 存储未扩展的参数包

c - 是否有可用的跨平台 C 信号库(更好的开源)?

无法将 TCP 套接字添加到使用 SDL_NET 设置的套接字

c# - 如何提高大量较小文件的读写速度或性能

c - 解析具有特定关键字匹配的文本文件

c++ - 为什么未分配的 int 有值?

windows - 更改 .bat 文件中的代码页(Win7 与 Win Vista)

python - 如何创建动态图以在 Flask 上显示?