我用CSocket编写了一个HTTP下载程序,接收数据大概如下:

//......
//use CSocket class
//send request...
//......
int recevieSize();
while(recevieSize > )
{
ZeroMemory(buff, BUFFSIZE + );
receviedSize = socket.Receive(buff, BUFFSIZE);
    if(receivedSize > 0)
{
//use CFile class
downloadFile.Write(buff, receviedSize);
//some handle...
}
 } //some handle...

  这段代码看上去毫无问题,但是运行过程中,在下载文件时,途中经常会出现ERROR_INVALID_USER_BUFFER错误,根据MSDN上的解释:“The supplied user buffer is not valid for the requested operation.”

  于是我尝试加大了缓冲区,但是问题依旧。这让我百思不得其解,上CSDN发帖问,也没人回答。于是我用CInternetSession、CHttpFile重写了这部分。这时候运行起来就毫无问题了,这让我更觉得奇怪了。

  后来根据这个stackoverflow上的这个帖子(http://stackoverflow.com/questions/12643441/win-32-writefile-access-viloation-and-error-1784),再仔细调试一下这两种代码,发现区别就在于两种代码每次写入文件的byets,因为CHttpFile::Read()每次返回固定的bytes,而CSocket::Receive()每次接收的bytes是不确定的,所以使用CSocket::Receive()接收数据每次写入文件的bytes也就不一样,根据帖子上的描述,问题应该就在这里了。

于是把代码改为这样:

//......
//use CSocket class
//send request...
//......
int recevieSize();
int readSize;
while(recevieSize > )
{
ZeroMemory(buff, BUFFSIZE + );
//downloadSize是此次任务需要下载的总bytes大小
readSize = downloadSize> BUFFSIZE ? BUFFSIZE : downloadSize;
receviedSize = socket.Receive(buff, readSize);
readSize -= receviedSize;
while(readSize && (receviedSize > ))
{
int rs = socket.Receive(buff + receivedSize, readSize);
if(rs == )//connection has been close
break;
else if(rs == SOCKET_ERROR)
{
receviedSize = rs;
break;
}
receivedSize += rs;
readSize -= rs;
}
if(receivedSize > )
{
//use CFile class
downloadFile.Write(buff, receviedSize);
//some handle...
}
}
//some handle...

  这样就保证了每次写入文件的bytes数,这样运行起来就不会出现ERROR_INVALID_USER_BUFFER了。但是为什么每次写入相同的bytes数就没问题呢?目前我也还没完全搞懂。

readSize

最新文章

  1. 安装 sublime2 (包括插件)
  2. VS Code 配置Python
  3. it转行了
  4. 采购信息记录修改[BDC]
  5. Maven提高篇系列之(四)——使用Profile
  6. jquery中prop()方法和attr()方法的区别浅析
  7. BZOJ2115 [Wc2011] Xor
  8. Django1.6添加comments应用的简单过程
  9. 电话qie听器
  10. java.util.zip压缩打包文件总结二: ZIP解压技术
  11. iOS开发手记 - iOS9.3 UINavigationController添加后不显示storyboard中viewcontroller里的控件的解决方法
  12. 高性能C++网络库libtnet实现:IOLoop
  13. JavaSE基础知识(5)—面向对象(5.7 final关键字)
  14. C++ 对象实例化(转)
  15. Linux 命令查询工具
  16. 大数据入门第二十五天——logstash入门
  17. MySQL 简单存储过程实现Redis的INCR功能
  18. FastJson之JsonObject, JsonString, JavaBean,List快速转换
  19. 【模板/经典题型】带有直线限制的NE Latice Path计数
  20. LDA和PCA区别

热门文章

  1. unity Transform.TransformPoint
  2. vmware esxi 过期,激活
  3. 【转】在ASP.NET应用启动的时候初始化的几种方法
  4. C++操作 SQL数据库 实例 代码步骤
  5. 【Android】20.2 视频播放
  6. Azure Redis
  7. .net core相关博客
  8. jQuery请求维基百科[历史上的今天]
  9. poj 50道dp题
  10. tomcat架构分析(valve源码导读)