在IOCP(完成端口)编程中,我用一个类(ContextKey类)作为一个CompletionKey与完成端口进行绑定.如下代码所示// 创建一个ContextKey类
ContextKey * pKey = new ContextKey(newsocket); // 将此类与完成端口进行绑定
CreateIoCompletionPort( (HANDLE)newsocket, hIoCompletionPort,(DWORD)pKey, 0 );而ContextKey类结构如下:class ContextKey
{
public:
    SOCKET  socket;
    char    m_buf[1024];    ContextKey(SOCKET sock);
    ~ContextKey();    void ReceiveData();
    void ProcessData(DWORD dwNumRead);    .... // 其它变量或函数
};void ContextKey::ReceiveData()
{
   DWORD  flags = 0;
   DWORD  recvBytes =0;   WSABUF m_RecvBuf;
   m_RecvBuf.buf=m_buf;
   m_RecvBuf.len=1024;
   if (WSARecv(socket, 
            &m_RecvBuf,
       1, 
       &recvBytes, 
       &flags,
       &ovIn,  // 问题在这里!!!!!!!!!!!!!!!!!!!!
       NULL) == SOCKET_ERROR)
   {
if(ERROR_IO_PENDING != WSAGetLastError())
{
    printf("ErrorCode:%d\n",WSAGetLastError()); 
    return ;
}
   }
}
现在问题描述如下:
在类中的ReceiveData函数中,如果在WSARecv中填入&ovIn(ovIn为成员变量)作为参数,那么程序则无法正常接收数据,在WSAGetLastError()返回ERROR_INVALID_HANDLE错误.如果我在WSARecv中填入一个全局的OVERLAPPED变量(到时到指针作为参数),则程序可以程序接收数据.为什么成员变量中的OVERLAPPED变量会导致出错,而全局的OVERLAPPED变量则会正常运行呢?请问这是什么原因?谢谢在线等...

解决方案 »

  1.   

    不好意思,忘记将ovIn变量加入ContextKey类了.
    现在补充如下:class ContextKey
    {
    public:
        SOCKET  socket;
        char    m_buf[1024];
        OVERLAPPED  ovIn; // 加入此变量
        ContextKey(SOCKET sock);
        ~ContextKey();
        void ReceiveData();
    };
      

  2.   

    你的ContextKey类 有没有实例化? 没生成对象,自然没有对象里的成员变量,自然就报 无效句柄了不知道你的代码整个都是怎样的,以上只是猜测
      

  3.   

    已解决,一时疏忽没有将类中的OVERLAPPED进行初始化.所以才出问题.
    因为如果不是进行文件操作的话,OVERLAPPED中的OffsetHigh,则必须设定为0.
    在类中没有对ovIn进行初始化,则OffsetHigh中的值是一个随机(原内存)值,所以会出现问题
    而全局的变量之所以可以正常使用,那应该是在创建时会自动用0来初始化整个结构.刚好满足要求.本来以为可以随便填一个OVERLAPPED就可以了,谁知道....
      

  4.   


    已经实例化了,我以为这个OVERLAPPED在这种情况下只是一个形式上的结构,所以我没有对OVERLAPPED进行初始化才导致问题产生.没有想到它也是起作用的.