解决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

你可能感兴趣的:(socket通信)