应该是windows网络编程第二版里面提到过。现在整理一下。

1:在IOCP中投递WSASend返回WSA_IO_PENDING的时候,表示异步投递已经成功,但是稍后发送才会完成。这其中涉及到了三个缓冲区。
网卡缓冲区,TCP/IP层缓冲区,程序缓冲区。
情况一:调用WSASend发送正确的时候(即立即返回,且没有错误),TCP/IP将数据从程序缓冲区中拷贝到TCP/IP层缓冲区中,然后不锁定该程序缓冲区,由上层程序自己处理。TCP/IP层缓冲区在网络合适的时候,将其数据拷贝到网卡缓冲区,进行真正的发送。
情况二:调用WSASend发送错误,但是错误码是WSA_IO_PENDING的时候,表示此时TCP/IP层缓冲区已满,暂时没有剩余的空间将程序缓冲区的数据拷贝出来,这时系统将锁定用户的程序缓冲区,按照书上说的WSASend指定的缓冲区将会被锁定到系统的非分页内存中。直到TCP/IP层缓冲区有空余的地方来接受拷贝我们的程序缓冲区数据才拷贝走,并将给IOCP一个完成消息。
情况三:调用WSASend发送错误,但是错误码不是WSA_IO_PENDING,此时应该是发送错误,应该释放该SOCKET对应的所有资源。

2:在IOCP中投递WSARecv的时候,情况相似。
情况一:调用WSARecv正确,TCP/IP将数据从TCP/IP层缓冲区拷贝到缓冲区,然后由我们的程序自行处理了。清除TCP/IP层缓冲区数据。
情况二:调用WSARecv错误,但是返回值是WSA_IO_PENDING,此时是因为TCP/IP层缓冲区中没有数据可取,系统将会锁定我们投递的WSARecv的buffer,直到TCP/IP层缓冲区中有新的数据到来。
情况三:调用WSARecv错误,错误值不是WSA_IO_PENDING,此时是接收出错,应该释放该SOCKET对应的所有资源。

在以上情况中有几个非常要注意的事情:
系统锁定非分页内存的时候,最小的锁定大小是4K(当然,这个取决于您系统的设置,也可以设置小一些,在注册表里面可以改,当然我想这些数值微软应该比我们更知道什么合适了),所以当我们投递了很多WSARecv或者WSASend的时候,不管我们投递的Buffer有多大(0除外),系统在出现IO_PENGDING的时候,都会锁定我们4K的内存。这也就是经常有开发者出现WSANOBUF的情况原因了。

我们在解决这个问题的时候,要针对WSASend和WSARecv做处理
1:投递WSARecv的时候,可以采用一个巧妙的设计,先投递0大小Buf的WSARecv,如果返回,表示有数据可以接收,我们开启真正的recv将数据从TCP/IP层缓冲区取出来,直到WSA_IO_PENGDING.
2:对投递的WSARecv以及WSASend进行计数统计,如果超过了我们预定义的值,就不进行WSASend或者WSARecv投递了。
3:现在我们应该就可以明白为什么WSASend会返回小于我们投递的buffer空间数据值了,是因为TCP/IP层缓冲区小于我们要发送的缓冲区,TCP/IP只会拷贝他剩余可被Copy的缓冲区大小的数据走,然后给我们的WSASend的已发送缓冲区设置为移走的大小,下一次投递的时候,如果TCP/IP层还未被发送,将返回WSA_IO_PENGDING。
4:在很多地方有提到,可以关闭TCP/IP层缓冲区,可以提高一些效率和性能,这个从上面的分析来看,有这个可能,要实际的网络情况去实际分析了。

IOCP中在WSASend以及WSARecv的时候出现WSA_IO_PENDING情况的说明相关推荐

  1. IOCP中的socket错误和资源释放处理方法

    前言:  错误处理和socket释放, 是IOCP编程中的一大难点. 本文试图就IOCP设计中经常遇到的这个难题展开论述并寻找其解决方案, 事实上, 文中所述的解决方式不仅仅适用于IOCP, 它同样适 ...

  2. Python使用matplotlib绘制数据去重前后的柱状图对比图(在同一个图中显示去重操作之后同一数据集的变化情况)

    Python使用matplotlib绘制数据去重前后的柱状图对比图(在同一个图中显示去重操作之后同一数据集的变化情况) #仿真数据 import pandas as pd import numpy a ...

  3. windows10 中 python3 离线 安装包,没有 网络 的 情况下 安装 whl包

    windows10中python3离线 安装包,没有 网络 的 情况下 安装 包 下载whl文件 cd python.exe文件路径 pip download 包名 举例 whl 文件 复制到 没有 ...

  4. Chrome 插件:自己写的插件提示请停用以开发者模式运行的插件处理方法,该拓展程序未列在chrome网上应用商店中,并可能是在您不知情的情况下添加的解决办法

    Chrome 浏览器插件问题处理 第一章:问题描述 ① 问题一:请停用以开发者模式运行的插件 ② 问题二:该拓展程序未列在 chrome 网上应用商店中,并可能是在您不知情的情况下添加的 第二章:Ch ...

  5. 解决tomcat中temp文件夹出现项目的副本的情况

    解决tomcat中temp文件夹出现项目的副本的情况 TomcatMyeclipseXMLGoogle  在最近开发过程中出现过这样的情况,当我在myeclipse发布项目的时候,在tomcat的te ...

  6. 详解:Hive中的NULL的处理、优点、使用情况(注意)

    Hive中的NULL的处理.优点.使用情况 一:Hive中的NULL hive的使用中不可避免的需要对null.''(空字符串)进行判断识别.但是hive又别于传统的数据库. 1.不同数据类型对空值的 ...

  7. 解决:该扩展程序未列在 Chrome 网上应用店中,并可能是在您不知情的情况下添加的

    直接使用.crx安装或者不是从Chrome应用商店中安装的插件,插件在扩展列表中会被禁用,启用按钮无法勾选并且提示: "该扩展程序未列在 Chrome 网上应用店中,并可能是在您不知情的情况 ...

  8. 在jupytor中运行随机森林预测泰坦尼克旅客生存情况

    在jupytor中运行随机森林预测泰坦尼克旅客生存情况 数据集链接链接: link. 百度网盘:链接: https://pan.baidu.com/s/1_pQ-3iG4dr0hrvU_5hYUtg ...

  9. Win10系统,出现蓝牙图标在快捷框中消失的问题,以及在设置中也找不到相关蓝牙信息的情况的解决办法;

    Ⅰ.问题描述: 1.在Win10系统中不知道按到了哪个按钮或者出现了什么问题,此时的蓝牙标志并未显示出来: 其在设置中的显示以及快捷框中的结果为: A.快捷框中的显示: B.在设置中的显示为: 也是这 ...

最新文章

  1. 优秀的数据分析师应该具备哪些技能和特质?
  2. java实现123n_用Java编程 :输入一个正整数n,输出n!的值。 其中n!=1*2*3*…*n。 求高手指点...
  3. research paper for management science
  4. query上传插件uploadify参数详细分析
  5. matlab guide 将matlab处理过的图片保存
  6. 移动端开发meta标签 viewport 设置
  7. 国密 sm系列 java实现_国密标准SM3算法,java实现
  8. php fakepath,chrome上传图片 路径为c:/fakepath的解决办法
  9. excel小技巧之--自定义序列
  10. 服务器上的光信号出现红点怎么办,光纤猫光信号闪红灯无法上网怎么办
  11. 字符串的倒叙输出(直接倒叙和单词倒叙)
  12. 基于SAR影像的鱼塘提取
  13. 软件技术人员成长路线的设计
  14. Android开发经验
  15. 探究 | Elasticsearch如何物理删除给定期限的历史数据?
  16. JavaWeb企业实战项目(一):环境搭建-用户注册-邮件发送
  17. VS Code + phpstudy实现PHP环境配置
  18. Linux技术(1)--CentOS 6.5关闭防火墙步骤
  19. office回退版本,从2021到2019
  20. OMA Download 入门

热门文章

  1. mybatisdb.sql
  2. 配置jvm堆最大内存eden区与s0或者s1区域比例
  3. mysql的索引介绍_1
  4. JAVA中ListIterator和Iterator详解与辨析
  5. linux将变量保存生成txt,linux-将输出命令保存在变量中并写入for循环
  6. MongoEngine MongoDB 的 ORM 库
  7. mybatis中条件表达式if的test为字符串时值比较
  8. React版本更新及升级须知(持续更新)
  9. 跟着《架构探险》学轻量级微服务架构 (一)
  10. 从“负电价”说起:谈谈德国新能源消纳的借鉴意义