zoukankan      html  css  js  c++  java
  • 解决SOCKET通信 ERROR_INSUFFICIENT_BUFFER错误

    错误发生在服务端异步收到一个socket连接,之后使用WSAGetLastError()得到的IO错误码是122

    这个错误码在系统中的解释是The data area passed to a system call is too small.   就是说前面的某个buffer设置的太小,看一下上一个调用的winapi是acceptEx这个函数;下面是代码(这是错误的)

        tRtn = lpfnAcceptEx(
            mListenSocket, tpOverlapEx->mCommSocket,
            tAcceptRecvBuf, 0,    // 表示只接收连接,不接收数据
            sizeof(sockaddr_in), sizeof(sockaddr_in),
            &dwBytes, (LPOVERLAPPED)tpOverlapEx);

    检查一下tAcceptRecvBuf和overlapEx中的buf,都设置了一K的大小,应该不是这两个buf出现问题的,再看一下acceptEx这个函数在msdn中的原型:

    BOOL AcceptEx(
      _In_   SOCKET sListenSocket,
      _In_   SOCKET sAcceptSocket,
      _In_   PVOID lpOutputBuffer,
      _In_   DWORD dwReceiveDataLength,
      _In_   DWORD dwLocalAddressLength,
      _In_   DWORD dwRemoteAddressLength,
      _Out_  LPDWORD lpdwBytesReceived,
      _In_   LPOVERLAPPED lpOverlapped
    );

    再看一下msdn上面提供的demo写法

        bRetVal = lpfnAcceptEx(ListenSocket, AcceptSocket, lpOutputBuf,
                     outBufLen - ((sizeof (sockaddr_in) + 16) * 2),
                     sizeof (sockaddr_in) + 16, sizeof (sockaddr_in) + 16, 
                     &dwBytes, &olOverlap);

    和我写的代码对比一下,发现问题了,我的代码是

    sizeof(sockaddr_in), sizeof(sockaddr_in),

    而demo的代码是

    sizeof (sockaddr_in) + 16, sizeof (sockaddr_in) + 16,

    再看一下msdn对这两个参数的解释

    dwLocalAddressLength [in]

    The number of bytes reserved for the local address information. This value must be at least 16 bytes more than the maximum address length for the transport protocol in use.

    dwRemoteAddressLength [in]

    The number of bytes reserved for the remote address information. This value must be at least 16 bytes more than the maximum address length for the transport protocol in use. Cannot be zero.

    “要比系统给的最大地址长度至少要多16个字节”,而我的代码没有多这16个字节,问题就出在这里,修改一下,再运行,就没问题了;

    话说回来,为什么要多16个字节,这是系统指定的,它没说为什么,蛋疼!

    关于这个函数的一些其它知识,可以参考这个连接

    http://bbs.csdn.net/topics/60370188

  • 相关阅读:
    C#与数据库访问技术总结(十四)之DataAdapter对象
    《运维三十六计》:运维生存宝典
    企业运维几百个重点面试题汇总(老男孩)
    5、KVM虚拟化典型案例:生产环境问题案例与分析
    Linux运维必会的实战编程笔试题(19题)
    面试中常见的 MySQL 考察难点和热点
    Linux系统运维常见面试简答题(36题)
    一键备份脚本 backup.sh
    Linux常用的200个命令总结分类
    2、KVM虚拟化CPU、内存、网络、磁盘技术及性能调优方法
  • 原文地址:https://www.cnblogs.com/emyueguang/p/3607159.html
Copyright © 2011-2022 走看看