IOCP AcceptEx 在连接时未创建完成

2024-04-24

我目前正在尝试一些用于套接字编程的新库(IOCP)。我偶然发现了AcceptEx http://msdn.microsoft.com/en-us/library/windows/desktop/ms737524%28v=vs.85%29.aspx启用异步连接的功能。

正如文档所说:

与accept函数不同,AcceptEx函数使用重叠I/O。如果您的应用程序使用 AcceptEx,它可以使用相对较少的线程为大量客户端提供服务。与所有重叠的 Windows 函数一样,Windows 事件或完成端口都可以用作完成通知机制。

但是当客户端连接时我没有收到任何完成信息。然而,当客户端发送数据时,我确实完成了。

这是我的代码:

DWORD dwBytes;
GUID GuidAcceptEx = WSAID_ACCEPTEX;
int iResult = WSAIoctl(m_hSocket, SIO_GET_EXTENSION_FUNCTION_POINTER,
    &GuidAcceptEx, sizeof (GuidAcceptEx), 
    &m_lpfnAcceptEx, sizeof (m_lpfnAcceptEx), 
    &dwBytes, NULL, NULL);

if (iResult == SOCKET_ERROR)
{
    CloseSocket();
}

进而:

WSAOVERLAPPED olOverlap;
memset(&olOverlap, 0, sizeof (olOverlap));
char lpOutputBuf[1024];
int outBufLen = 1024;
DWORD dwBytes;

BOOL bRet = m_lpfnAcceptEx( m_hSocket, hSocket, lpOutputBuf,
             outBufLen - ((sizeof (sockaddr_in) + 16) * 2),
             sizeof (sockaddr_in) + 16, sizeof (sockaddr_in) + 16, 
             &dwBytes, &olOverlap);
if ( bRet == FALSE )
{
    DWORD dwRet = WSAGetLastError();
    if( dwRet != WSA_IO_PENDING )
    {
        return dwRet;
    }
}

关于如何接收完成的任何建议?

编辑: 我在 m_lpfnAcceptEx() 之后将 hSocket 绑定到完成端口


首先是WSAOVERLAPPED以及您在调用上方的堆栈上声明的数据缓冲区AcceptEx()当完成发生时将不存在(除非您调用GetQueuedCompletionStatus()在同一个函数中,这有点奇怪)。您需要动态分配它们或池化它们。

其次,您声明在调用后将套接字关联到完成端口AcceptEx()。那是错误的。打电话之前你需要做这些事情AcceptEx().

  1. 创建一个套接字WSA_FLAG_OVERLAPPED set.
  2. 将其绑定到您要收听的地址。
  3. 致电收听您想要的积压工作。
  4. Load AcceptEx()动态地使用监听套接字并调用WSAIoctl(不是绝对必要的,您显示的代码应该可以工作,但这样您就可以确保您从相同的底层winsock提供程序获取侦听套接字并且它支持AcceptEx()。
  5. Load GetAcceptExSockaddrs()以与加载相同的方式AcceptEx()- 接受完成后您将需要它。
  6. 将侦听套接字关联到您的 IOCP。

现在您可以发布一些AcceptEx()使用侦听套接字和您创建的新“接受”套接字进行调用,如下所示:

  1. 创建一个套接字WSA_FLAG_OVERLAPPED set.
  2. 将套接字关联到您的 IOCP。

如上所述,您需要确保缓冲区和 OVERLAPPED 每次调用都是唯一的,并且持续到完成为止。

完成后,您必须执行以下操作......

  1. Call setsockopt() with SO_UPDATE_ACCEPT_CONTEXT在接受的套接字上使用侦听套接字作为数据...
  2. 使用以下方式解锁您的地址GetAcceptExSockaddrs().
  3. 处理任何数据(如果您在缓冲区中为数据分配了足够的空间)。

请注意,根据设计AcceptEx()可用于接受新连接并在一次操作中从该连接返回初始数据(在您知道在开始执行操作之前总是需要一些数据但管理起来非常复杂的情况下,这会导致性能稍好一些你想防御拒绝服务攻击,这种攻击可以通过连接而不是发送数据来发起 - 我写过这个here http://www.serverframework.com/products---the-free-framework.html).

如果你不想AcceptEx()等待数据到达,然后只需提供一个数据缓冲区,该缓冲区仅足够大以返回地址,并传递 0 作为“缓冲区大小”。这将导致AcceptEx()像重叠一样操作accept()并在连接建立后立即返回。

请注意,马丁·詹姆斯对您问题的最初评论实际上就是您正在寻找的答案。不要通过outBufLen - ((sizeof (sockaddr_in) + 16) * 2), pass 0.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IOCP AcceptEx 在连接时未创建完成 的相关文章

  • Microsoft Visual C++ 2008 和 R2007b 的 Mex 类型

    我想对 vs2008 和 matlab2007b 使用 mex 类型 我尝试了下面的代码 include
  • C++ 中的可变参数函数声明中省略了逗号

    我习惯于这样声明可变参数函数 int f int n 读书时C 编程语言我发现书中的声明省略了逗号 int f int n the comma has been omitted 这个语法似乎是 C 特定的 因为当我尝试使用 C 编译器编译它
  • C# 中的 DateTime.Parse 抛出异常

    我不知道为什么抛出异常 这是工作代码 DateTime Parse 1 12 2012 12 00 00 AM 这是抛出异常的一个 DateTime Parse 1 13 2012 12 00 00 AM 抛出的异常是 格式异常 包括此消息
  • CRTP 能否完全取代小型设计的虚拟功能?

    Is CRTP http en wikipedia org wiki Curiously recurring template pattern有足够的能力智胜virtual功能齐全 我认为 CRTP 的唯一缺点是为每个重复模式生成大量代码
  • float.Parse 不再在 Unity 中工作 (C#)

    我有一个包含以下代码行的工作项目 public InputField mass float val float Parse mass text 非常简单 用户输入一定量的质量 然后将其从文本解析为浮动 几天前这工作得很好 我什至能够多次导出
  • 可空引用类型意外 CS8629 可空值类型对于临时变量可能为空

    在 C 8 项目中 我使用可为 null 的引用类型 并收到意外的 或者至少对我来说意外的 CS8629 警告 bool singleContent x DataInt null bool multiContent x DataNvarch
  • 如何测试 PARTIAL 视图在 C# ASP .NET MVC 中呈现

    我有一个视图 它内部有部分视图渲染 div class partialViewDiv Html RenderPartial partial Model SomeModelProperty div 和一个返回此视图的控制器 public Ac
  • 一个阻塞但非模态的 QDialog?

    我有一堆图像 我想对其执行一些操作 处理完每个图像后 我的程序应该弹出一个对话框 提示用户是否要继续处理下一个图像或中止 在此之前 他们应该有机会对图像或参数进行一些手动更改 无论如何 他们必须能够访问应用程序的窗口 而调用对话框的方法的执
  • 类模板的可变参数构造函数模板的特化

    这是一个带有可变参数构造函数的类 它专门用于从临时对象进行复制和移动 template
  • 我应该在查询时调用 ToListAsync()

    不久前 我开始接触 C 并正在寻找一些如何编写代码的最佳实践 现在 我正在使用 EF Core 并具有以下代码 var details dbContext Details Where x gt x Name Button foreach v
  • 在javascript中调用c#函数[重复]

    这个问题在这里已经有答案了 可能的重复 从 Javascript 调用 ASP NET 函数 https stackoverflow com questions 3713 call asp net function from javascr
  • 在 QtCreator 中查看数组内容

    调试时是否可以在 Qt Creator 中查看数组的内容 似乎检测到我的数组是一个数组而不是一个指针 此外 我可以点击一个箭头 就像展开一样 但之后什么也没有显示 当我试穿的时候std vector Qt Creator 设法按预期显示内容
  • 在 Winforms 中,PreviewKeyDown() 从未针对任何键触发

    我最初试图让我的程序获取箭头键 上 下 左 右 的输入 但发现在 KeyDown 中这些键从未出现过 后来我发现我可以通过进入 PreviewKeyDown 函数并设置来启用箭头键 e IsInputKey true 及其周围的任何条件和逻
  • gcc总是做这种优化吗? (公共子表达式消除)

    作为示例 假设表达式sys gt pot atoms item gt P kind mass在循环内求值 循环只改变item 因此表达式可以简化为atoms item gt P kind mass通过将变量定义为atoms sys gt p
  • 如何使用实体框架更新特定记录的一个字段?

    我想要更新一个名叫 Pejman 的人的家庭情况 这是我的对象类 public class Person public int Id get set public string FirstName get set public string
  • C/C++ 特殊 CPU 功能的使用

    我很好奇 新的编译器是否使用了新 CPU 中内置的一些额外功能 例如 MMX SSE 3DNow 所以 我的意思是 在最初的 8086 中甚至没有 FPU 所以旧的编译器甚至不能使用它 但新的编译器可以 因为 FPU 是每个新 CPU 的一
  • 在 Qt C++ 中使用多个键

    我正在构建 坦克 游戏 我使用关键事件在地图上运行我的坦克 实际上我当时只能使用一把钥匙 但我需要有能力去完成任务 同时向上和离开 这是我的单键事件代码 switch event gt key case Qt Key Up if ui gt
  • 使用 std::set 时重载运算符<

    这是我第一次使用 std set 容器 并且我对操作符 std less 遇到了问题 我声明该集合 std set
  • C++ 中的 Ofstream 数组

    我想要在我的项目中使用 41 个输出文件来在其上写入文本 首先创建一个字符串数组list为了命名这些输出文件 然后我尝试定义一个 ofstream 对象数组并使用list命名它们 但我收到此错误 outfile cannot be used
  • 如何注销多个非当前用户的会员用户?

    我正在使用属于 MVC2 默认项目一部分的 MembershipProvider 我希望能够获取用户名列表 注销用户 并在需要时销毁他们的会话 我能想到的最接近的是 foreach string userName in UserNames

随机推荐

  • DYMOLA:opc 服务器如何使用 MATLAB 使用 dsin.txt 或 mat 文件进行初始化

    我在 DYMOLA 中创建了一个 OPC 服务器 现在我在 DYMOSIM 中有这个可以单击并初始化 使用 dsin txt 的 MAT 文件 现在我在 MATLAB 中创建了一个 GUI 文件 并获取变量的输入并创建了一个 mat 文件
  • 无法构建轮子 - 错误:无效命令“bdist_wheel”

    我已经尝试了这个非常相关的问题中的所有内容 为什么我无法在 python 中创建轮子 https stackoverflow com questions 26664102 why can i not create a wheel in py
  • postgresql自连接

    假设我有一张这样的桌子 id device cmd value id unique row ID device device identifier mac address cmd some arbitrary command value v
  • Rails:创建删除表级联迁移

    如何在 Rails 3 2 迁移中强制执行 DROP TABLE CASCADE 是否有一个选项可以传递给 drop table table name 在 Rails 4 中 您可以执行以下操作 drop table accounts fo
  • 如何使用在单击按钮上创建的用户触发图表中的放大和缩小?

    我正在构建一个角度应用程序 其中我们需要创建用于放大和缩小图表的单击按钮 我们可以使用可悬停模式栏上的按钮放大缩小图表 但这对于我们的应用程序来说不是必需的 我们希望使用通过单击按钮创建的用户来放大和缩小图表 有没有办法使用单击按钮触发可悬
  • Electron如何拦截http响应体

    有什么办法可以拦截BrowserWindow主进程中的http响应主体没有调试器 是否无法使用WebRequest类和onCompleted method 我可以使用调试器做到这一点 但由于某种原因我不能使用它 await w webCon
  • 在 Eclipse (Spring Source) 中,Grails 始终以生产模式构建

    当在 Grails 项目中使用 Eclipse 时 战争的构建似乎陷入了生产模式 如果您想部署到附加的 tcServer 您只需右键单击您的项目 然后选择 运行方式 gt 在服务器上运行 如果您将 grails 项目设置为 dev 右键单击
  • 气流:Dag 每隔几秒安排两次

    我尝试每天仅运行一次 DAG00 15 00 午夜 15 分钟 然而 它被安排了两次 间隔几秒钟 dag DAG my dag default args default args start date airflow utils dates
  • 显式语义分析

    我遇到了这个术语 显式语义分析 它使用维基百科作为参考 找到文档中的相似性并将它们分类 如果我错了 请纠正我 我遇到的链接是here http www cs technion ac il gabr resources code esa es
  • 十进制铸造

    我有一个这样的十进制数 62 000 0000000 我需要将该小数转换为 int 它的小数总是为零 所以我不会失去任何精度 我想要的是这样的 62 000 存储在 C 中的 int 变量中 我尝试了很多方法 但它总是给我一个错误 字符串的
  • Python列表来存储类实例?

    给定一个 python 类class Student 和一个清单names 然后我想创建几个实例Student 并将它们添加到列表中names names For storing the student instances class St
  • 如何将html页面的动态内容转换为pdf

    在 html 页面中 一些标签是使用 jquery 动态创建的 内容是使用 jquery 和 php 从 msql 数据库加载的 我想将这个动态页面转换为pdf 我尝试过以下代码 但它生成 html 页面静态部分的 pdf html cod
  • 在 C++ 中正确地将 `void*` 转换为整数

    我正在处理一些使用外部库的代码 您可以在其中通过void value 不幸的是 前一个处理此代码的人决定通过将整数转换为 void 指针来将整数传递给这些回调 void val 我现在正在努力清理这个混乱 并且我正在尝试确定将整数转换为整数
  • 估计命令如何查找 R 公式中的变量名称?

    我想使用 R 来估计大量模型nls 函数作用于用户定义的函数 由于许多变量在我的规范中是固定的 我想要一种在我的函数中预先设置它们的方法 但我没有正确理解 R 如何在公式中包含的函数中查找变量 我看过 Hadley Wickham 的高级
  • 我无法获取 servlet 页面中的 POST 值?

    我无法在 servlet 页面中获取 POST 值 我之前的问题与这个问题相关 如何从servlet页面中的ajax请求获取数据 https stackoverflow com questions 6042177 how to get th
  • 如何找到已安装的pandas版本

    我在使用 Pandas 的某些功能时遇到问题 如何查看我的安装版本是什么 Check pandas version In 76 import pandas as pd In 77 pd version Out 77 0 12 0 933 g
  • pytorch 中的 autograd 可以处理同一模块中层的重复使用吗?

    我有一层layer in an nn Module并在一次中使用两次或多次forward步 这个的输出layer稍后输入到相同的layer pytorch可以吗autograd正确计算该层权重的梯度 def forward x x self
  • 在应用程序启动时禁用 Windows 服务

    因为我必须在应用程序启动时关闭 Windows 高级文本服务 有什么特殊的API吗 它适用于具有默认权限的用户吗 该问题的标题是 禁用 Windows 服务 但答案都告诉我们如何停止服务 您在 Google 上会发现的大部分内容是 您可以使
  • 无法在 gae 中运行简单的 helloworld (python 2.7)

    我正在尝试运行官方你好世界 https shadyabhi github com shadyabhi helloworld gitgoogle appengine 1 6 4 中用于 python 2 7 的程序 无法运行一个简单的 hel
  • IOCP AcceptEx 在连接时未创建完成

    我目前正在尝试一些用于套接字编程的新库 IOCP 我偶然发现了AcceptEx http msdn microsoft com en us library windows desktop ms737524 28v vs 85 29 aspx