IOCP 文档解释问题 - 缓冲区所有权歧义

2023-12-03

因为我不是以英语为母语的人,所以我可能会错过一些东西,所以也许这里有人比我更了解。

取自WSASendMSDN 上的文档:

lpBuffers [输入]

指向 WSABUF 数组的指针 结构。每个WSABUF结构 包含一个指向缓冲区的指针和 缓冲区的长度(以字节为单位)。为一个 Winsock应用程序,一旦WSASend 函数被调用,系统拥有 这些缓冲区和应用程序可能 不访问它们。该数组必须 在有效期内保持有效 发送操作。

好的,你能看到粗体文字吗?这就是不明白的地方!

我可以想到这句话的两种翻译(可能是别的东西,你能想到的):
翻译 1 -“缓冲区”指的是重叠结构我在调用它时传递了这个函数。仅当收到有关该对象的完成通知时,我才可以再次重用该对象。
翻译 2 -“缓冲区”指的是实际缓冲区,那些包含我要发送的数据的人。如果 WSABUF 对象指向一个缓冲区,那么在操作完成之前我无法触及该缓冲区。

谁能告诉这句话的正确解释是什么?

还有......如果答案是第二个——你会如何解决它?
因为对我来说,这意味着对于我发送的每个数据/缓冲区,我必须在发送方保留它的副本 - 因此在高流量应用程序上有许多“待处理”缓冲区(不同大小),这确实会发生损害“可扩展性”。

声明一:
除了上面的段落(“和...”)之外,我认为 IOCP 会将要发送的数据复制到它自己的缓冲区并从那里发送,除非您设置SO_SNDBUF为零。

声明2:
我使用堆栈分配的缓冲区(你知道,类似char cBuff[1024];在函数体中 - 如果对主要问题的翻译是第二个选项(即缓冲区必须保持原样,直到发送完成),那么......这真的把事情搞砸了!你能想个办法解决吗? (我知道,我在上面换句话说)。


答案是,在操作完成之前,重叠结构和数据缓冲区本身无法重用或释放。

这是因为操作是异步完成的,因此即使数据最终被复制到 TCP/IP 堆栈中操作系统拥有的缓冲区中,也可能要等到将来某个时间才会发生,并且您会收到写入完成发生的通知。请注意,如果您在没有显式流量控制的情况下发送并依赖 TCP 堆栈为您进行流量控制,则在写入完成时,这些可能会延迟令人惊讶的时间(请参见此处:使用 WSASend 的一些重叠未使用 GetQueuedCompletionStatus 及时返回?) ...

您不能使用堆栈分配的缓冲区,除非您将事件放置在重叠结构中并阻止它直到异步操作完成;这样做没有多大意义,因为你会比正常的阻塞调用增加复杂性,并且通过发出异步调用然后等待它也不会获得很多好处。

在我的 IOCP 服务器框架中(您可以从here)我使用动态分配的缓冲区,其中包括重叠结构并且是引用计数的。这意味着当完成发生并且引用被释放时,就会发生清理(在我的例子中,它们被返回到池中以供重用)。这也意味着您可以选择在操作后继续使用缓冲区,并且清理仍然简单。

另请参阅此处:I/O 完成端口,如何释放每个套接字上下文和每个 I/O 上下文?

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

IOCP 文档解释问题 - 缓冲区所有权歧义 的相关文章

  • Eclipse下C语言的Socket编程(Winsock,gcc)问题总结

    最近心血来潮想从新温习一下C语言 xff08 工作后一直用Java xff0c 其实大学时C语言课程也没好好上 xff0c 正经的代码基本没写过 xff0c 惭愧啊 xff01 xff09 xff0c 找了些小例子 xff0c 修修改改 x
  • 利用Winsock实现UDP通信

    UDP通信的C语言实现 UDP通信的定义Winsock用于通信的结构体服务端socket建立服务端程序源码用户端socket建立用户端程序源码信息的接收与发送UDP通信的特点 UDP通信的定义 Internet 协议集支持一个无连接的传输协
  • epoll移植到windows的可行性研究

    1 各有千秋 linux作为高效稳定的操作系统 部署在大量的服务器上 epoll在linux下 一个高性能的网络IO模型 在服务端领域发挥着重要的作用 但在开发效率上 windows以及visual studio系列因其良好的用户体验而更受
  • .NET 中工作线程和 I/O 线程的简单描述

    在 NET 中很难找到工作线程和 I O 线程的详细但简单的描述 我对这个主题的了解很清楚 但技术上可能不准确 工作线程是这样的线程should使用 CPU 来完成工作 I O 线程 也称为 完成端口线程 should使用设备驱动程序来完成
  • 如何在 Windows 上取消 select() 中的等待

    在我的程序中 有一个线程 接收线程 负责从 TCP 套接字接收请求 并且有许多线程 工作线程 负责处理接收到的请求 处理请求后 我需要通过 TCP 发送答案 这是一个问题 我想在用于接收数据的同一个线程中发送 TCP 数据 该线程接收数据后
  • 获取有关已安装网络适配器的信息

    我在 Windows XP sp3 上使用 Delphi XE2 Update 4 我希望从已安装的网络适配器中获取尽可能多的信息 特别是广播 IP 为此 我使用了 Jan Schulz 提供的代码从这篇文章 Unit Unit USock
  • 如何正确解析传入的 HTTP 请求

    我使用 WinSck 创建了一个 C 应用程序 它实现了一个小型 仅处理我需要的一些功能 http 服务器 这用于使用 http 请求与外界进行通信 它可以工作 但有时请求无法正确处理 因为解析失败 现在我非常确定请求的格式正确 因为它们是
  • 关于Winsock Kernel Buffer和Nagle算法的疑问

    在读的时候this http support microsoft com kb 214397文章 我有一个疑问 据我了解 在传输小数据时 默认情况下会启用 Nagle 算法 该算法会合并小数据包 这会导致在传输之前缓存一些数据 我相信 Wi
  • Winsock C++ 连接超时

    我正在尝试为 connect 函数设置自己的超时 我的代码在默认连接下运行良好 如下所示 bool connectFUNC4 char ipaddr WSADATA wsa struct sockaddr in server if WSAS
  • 通过多个套接字传输文件是否比仅使用一个套接字更快?

    在这个旧 从 2002 年开始 它说如果您将一个文件分成多个块 然后使用不同的套接字传输每个块 那么它的到达速度将比使用一个套接字将其作为一个整体传输要快得多 我还记得 很多年前 读过一些下载管理器也使用这种技术 这有多准确 鉴于具有大窗口
  • 为什么 Socket.AcceptAsync 不触发 SocketAsyncEventArgs Completed 事件?

    我正在开发一个服务器应用程序 它将接收消息并做出响应 没什么新鲜的 所以 实际上我正在关注这个答案 https stackoverflow com questions 869744 how to write a scalable tcp i
  • C++ 挂钩 winsock

    我正在尝试挂接winsock send 和recv 以读取进程的所有流量 我将以下代码作为 dll 注入目标进程中 include dll h include
  • IOCP多线程服务器和引用计数类

    我在 IOCP 服务器上工作 重叠 I O 4 线程 CreateIoCompletionPort GetQueuedCompletionStatus WSASend 等 我的目标是向所有连接的套接字发送单个引用计数缓冲区 我遵循了 Len
  • 将套接字句柄从 .NET 传递给非托管子进程

    我当前有一个 NET 程序启动与服务器的连接并启动另一个非托管可执行文件 本机进程应该接管相同的套接字 在子进程终止之前不要关闭连接至关重要 并开始通过它与服务器进行通信 上述程序都在 Windows 上运行 但我更喜欢不涉及 NET 部分
  • 如何使用winsock的send()函数发送宽字符?

    It says here http msdn microsoft com en us library ms740149 28VS 85 29 aspx发送函数需要 const char 如何发送宽字符 我尝试了以下方法 void MyCla
  • winsock中的异步地址解析?

    查看winsock中的异步地址解析 似乎唯一的两个选择是使用阻塞gethostbyname在单独的线程上 或使用WSAAsyncGetHostByName 出于某种原因 后者被设计为处理窗口消息 而不是重叠操作和完成端口 例程 有没有什么版
  • 如何提取消息的长度信息并从 TCP 字节流中仅提取那么多消息?

    我正在尝试通过 C 中的 Socket 发送消息 我已经阅读了许多与此相关的堆栈溢出问题 但仍然无法弄清楚它是如何工作的 假设我正在向本地主机服务器发送以下字符 M a r t i n 人们建议您可以使用 4 个字节作为长度 即 32 位
  • 如何设置Winsock UDP套接字?

    我想创建一个仅向客户端发送数据的 Winsock UDP 套接字 我希望内核为我选择一个可用的端口 另一方面 我想指出要使用哪个本地 IP 因为我正在运行一些网卡 我尝试过梳理迷宫般的套接字选项 以及将套接字地址中的端口绑定设置为 0 但均
  • XP 和 Vista 之间使用 Winsock API 的 UDP 多播差异

    Windows XP 和 Windows Vista 之间设置 UDP 多播套接字所需的实现似乎有所不同 具体来说 在 Windows XP 下 您must call bind 在您可以引用任何特定于多播的套接字选项之前 然而 在windo
  • 如何将 OpenSSL 与 WinSock 一起使用?

    我在网上搜索过 但没有找到任何与此相关的内容 有谁有使用 WinSock 和 OpenSSL 的简单代码示例吗 我正在寻找一个简单的 Visual C 2005 或更高版本的代码示例 它创建并打开一个 Winsock 连接 并使用 Open

随机推荐

  • Git 命令显示 .gitignore 忽略了哪些特定文件

    我正在接触 Git 并遇到以下问题 我的项目源树 src refs vendor 我的供应商分支中有代码 当前为 MEF 我将在那里进行编译 然后将引用移至 src refs这就是项目从中获取它们的地方 我的问题是我有我的 gitignor
  • 如何使用jquery获取输入是否具有焦点[重复]

    这个问题在这里已经有答案了 如何使用jquery获取html的输入标签是否具有焦点 如果输入 图像等标签具有焦点 则 keydown 事件将适用于表单 但它不会工作 它的重点是形式 而不是任何标签 如输入 图像等 我该如何解决这个问题 请帮
  • 将 BCD 转换为二进制的最有效方法

    我有下面的代码将 32 位 BCD 值 以两个 uint 半部分提供 转换为 uint 二进制值 提供的值最大可达 0x9999 形成最大值 0x99999999 有没有更好 即更快 的方法来实现这一目标
  • for line in File 是否读取整个文件

    以下代码是为每个循环读取一行 还是在开始迭代之前先将整个文件读入内存 for line in f print line 我的目的是从文件中读取一行 你无法确定 你所能知道的就是它会return一次一行 这Python 标准库文档 says
  • 将多行连接成一行

    我现在正在学习SQL on SQL Server 我需要将多行连接成一列 我已经寻找过示例 但没有找到可以用来满足我的需求的示例 Country ProjectTA Complexity TID Sites Inits Name Unite
  • 主机和 GPU 上 CUDA 添加的不同结果

    我有一个函数可以获取彩色图片并返回其灰色版本 如果我在主机上运行顺序代码 一切都会完美运行 如果我在设备上运行它 结果会略有不同 与正确值相比 1000 个像素中的一个像素不是 1 就是 1 我认为这与转换有关 但我不确定 这是我使用的代码
  • html5 视频标签在 Android PhoneGap 中不起作用

    我已经在 android PhoneGap 中创建了应用程序 我想使用 html5 视频播放器播放视频 我的代码是
  • 追加时返回 null 的字符串

    我的任务是创建一个猜词游戏 您只有 5 次尝试猜测该单词的机会 用户一次输入一个字母 试图找出我的秘密单词 果汁 但您应该使用提示单词构造 每次猜测都会用正确的字母替换星号 如果正确 输出应该是这样的 欢迎来到猜词游戏 您有 5 次机会尝试
  • SQL Server 2008 中从数据库到数据集的位数据类型到枚举类型的映射

    我有一个表 其中有一列Xyz它有bitSQL Server 2008 中的数据类型 我通过数据适配器从表中获取值 并将其存储在DataSet and a DataGridView将显示来自的内容DataSet 在网格视图中 对于列Xyz 显
  • 鼠标光标位图

    我试图从鼠标光标获取位图 但在下一个代码中 我无法获取颜色 CURSORINFO cursorInfo 0 cursorInfo cbSize sizeof cursorInfo if GetCursorInfo cursorInfo IC
  • 如何在resilience4j中配置retryOnResultPredicate?

    我想将failAfterMaxAttempts设置为true以在最大重试结束时获得MaxRetriesExceededException 根据文档 我们需要使用failAfterMaxAttempts设置retryOnResultPredi
  • iOS7 itms-services 方案不起作用?

    我有一个内部应用程序 通过本地 WiFi 分发 在发布页面有一个像这样的链接 itms services action download manifest url http 192 168 1 231 app plist houseApp
  • Python OpenCV 从相机流式传输 - 多线程、时间戳

    我在 Raspberry Pi 3 上运行了简单的 python 脚本 该脚本负责打开视频设备并使用 MJPEG 将数据 800x600 流式传输到 HTTP 端点 当我收到此流时 我的 Raspberry Pi 核心之一可以 100 工作
  • 打印出带有字符的 ASCII 圆和轴

    我必须打印一个圆 将其半径 圆心的坐标作为输入 cx and cy 以及绘制它所用的字符 我为轴和圆编写了一系列 if 块 如果我单独使用它们 它们会很好地工作 但是当我将它们放在同一个方法中时 我必须只有一种方法 它们会以不期望的方式重叠
  • 使用多字符分隔符将字符串拆分为数组

    我需要将一个字符串拆分为一个数组 我的问题是分隔符是 3 个字符 例如 db2 111 oracle12cR1RAC mariadb101 我需要创建以下数组 db2 111 oracle12cR1RAC mariadb101 这种方法也提
  • :属性查找 thread.lock 失败' aria-label='multiprocessing.Pool - PicklingError:无法 pickle :属性查找 thread.lock 失败'> multiprocessing.Pool - PicklingError:无法 pickle :属性查找 thread.lock 失败

    multiprocessing Pool让我发疯了 我想升级许多软件包 对于每一个软件包 我都必须检查是否有更高的版本 这是由check one功能 主要代码在Updater update方法 我创建 Pool 对象并调用map 方法 这是
  • 如何将一个值从一个jsp页面传递到另一个jsp页面?

    我有两个jsp页面 search jsp and update jsp 当我跑步时search jsp然后从数据库中获取一个值 并将该值存储在一个名为scard 现在 我想要的是在另一个 jsp 页面中使用该变量的值 我不想使用reques
  • blogdown 主页不再显示帖子目录

    我正在使用 blogdown 0 14 和稍微修改过的hugo lithium 主题 创建的博客的主页似乎已更改 它曾经是一个带有帖子目录的页面 而不是一个带有指向显示该目录的页面的链接的页面 有没有办法恢复旧的行为 一小时前提到过在推特上
  • 根据屏幕尺寸替换 HTML

    我试图在小屏幕尺寸下替换 HTML 内容 然后在窗口再次变大时替换它 我下面的代码可以工作 但是我如何让它删除更改 到目前为止 这是我的代码 window resize function if window innerWidth lt 48
  • IOCP 文档解释问题 - 缓冲区所有权歧义

    因为我不是以英语为母语的人 所以我可能会错过一些东西 所以也许这里有人比我更了解 取自WSASendMSDN 上的文档 lpBuffers 输入 指向 WSABUF 数组的指针 结构 每个WSABUF结构 包含一个指向缓冲区的指针和 缓冲区