IOCP写的UDP!
在测试中,我不断的创建套接字,并在此套接字上发送和接收数据,会同时有很多个套接字在发送和接收数据!!!
运行一段时间之后,会弹出对话框报错:
Access violation at address 00000010 Read address of 00000010.
有时候还报错USER32.DLL中非法!!
郁闷了!!!!!
应该不是我代码中访问非法,应该是IOCP内部的报出来的,到底是怎么回事啊????
有哪位能给我说说,造成这个问题的可能原因也好!!!!!
我在网上也查了很多,但是都是说的TCP的IOCP,我在调试的过程中,查看日志,实在没看出来是什么问题,难道是overlapped结构的问题???我资源的释放是采取的引用计数方式来的,感觉应该没有什么问题!!!!!
有经验的,给我指点,谢谢!!!

解决方案 »

  1.   

    这是我的接受线程的部分代码:/接收线程
    unsigned __stdcall CSockBase::ReceiveThread( void* pArg )
    {
    CSockBase *pThis = (CSockBase*)pArg;
    assert(pThis != NULL);
    HANDLE hIOCP = pThis->GetIOCPHandle();
    assert(hIOCP != NULL);
    DWORD dwTrans = 0;
    DWORD dwKey = 0;
    PER_HANDLE_DATA *pHandleData = NULL;
    PER_IO_DATA *pIoData = NULL;
    BOOL bRet = FALSE;
    while(1)
    {
    bRet = GetQueuedCompletionStatus(hIOCP, &dwTrans, &dwKey, (LPOVERLAPPED*)&pIoData, INFINITE);
    pHandleData = (PER_HANDLE_DATA*)dwKey;
    if(!bRet)
    {
    if(GetLastError() == WAIT_TIMEOUT)
    {
    continue;
    }
    else
    {
    if(pIoData == NULL) //关闭套接字引起
    {
    ATLTRACE("---关闭套接字引起---\r\n");
    CAutoLock(&(pThis->m_ListIoInUsecs), "Receivethread");
    pThis->FreeIoData(pIoData, pHandleData);
    continue;
    }
    ATLTRACE("Quit from receive thread : %d  errorcode : %d \r\n", GetCurrentThreadId(), GetLastError());
    return -1;
    }
    }
    if(dwTrans == OPER_CLOSE && pHandleData->bIsClose)
    {
    while(pHandleData->dwSendOutstandingCount != 0)
    {
    ATLTRACE("未完成 Socket: %d Count: %d  \r\n", pHandleData->s, pHandleData->dwSendOutstandingCount);
    Sleep(10);
    }
    pThis->FreeHandleData(pHandleData);
    ATLTRACE("Complete  Closesocket  address : %x \r\n", dwKey);
    continue;

    }
    if(dwTrans == OPER_QUIT)
    {
    ATLTRACE(_T("Quit from receive thread: %d \r\n"), GetCurrentThreadId());
    break;
    }
    pThis->HandleIo(dwKey, dwTrans, (DWORD)pIoData);
    }
    return 0;
    }
    void CSockBase::HandleIo(DWORD dwKey, DWORD dwTrans, DWORD dwOvl)
    {

    INT nRet = 0;
    WSABUF buf;
    DWORD dwFlag = 0;
    INT nLen = sizeof(SOCKADDR);
    PER_HANDLE_DATA *pHandleData = (PER_HANDLE_DATA*)dwKey;//单句柄数据
    PER_IO_DATA *pIoData = (PER_IO_DATA*)dwOvl;//单IO数据
    if(pHandleData->bIsClose && pIoData->byOperType == OPER_READ)
    {
    ATLTRACE("Read rubbish packet socket: %x  bIsClose : %x handle address : %x Operation Type : %d \r\n",
    pHandleData->s, pHandleData->bIsClose, pHandleData, pIoData->byOperType);
    return;
    }

    switch(pIoData->byOperType)
    {
    case OPER_READ:
    {
    DATA *pData = AllocData();
    pData->dwIndex = (DWORD)pHandleData->s;
    memcpy(pData->szLocalIp, inet_ntoa(pHandleData->localAddr.sin_addr), IP_LEN);
    pData->wLocalPort = ntohs(pHandleData->localAddr.sin_port); //单IO数据
    assert(pIoData->ol.InternalHigh <= MAX_BUF);
    memcpy(pData->szData, pIoData->szBuf, pIoData->ol.InternalHigh);
    memcpy(pData->szPeerIp, inet_ntoa(pIoData->RemoteAddr.sin_addr), IP_LEN);
    pData->wDataLen = (WORD)pIoData->ol.InternalHigh;
    pData->wPeerPort = ntohs(pIoData->RemoteAddr.sin_port);
    while(!HasOverlappedIoCompleted(&pIoData->ol)) //等待overlapped结构完成
    {
    ATLTRACE("HandleIo didn't Complete \r\n");
    Sleep(0);
    }

    {
    CAutoLock LockList(&m_ListIoInUsecs, "HandleIo Read");
    FreeIoData(pIoData, pHandleData); //用完后释放IO数据
    InterlockedDecrement(&pHandleData->dwRecvOutstandingCount); //递减未决接收IO计数
    ATLTRACE("Release Io Buffer Recv Count : %d \r\n", pHandleData->dwRecvOutstandingCount);
    pIoData = NULL;
    }


    //投递接收请求
    pIoData = AllocIoData();
    ATLTRACE("AllocIoData for socket : %d  Address : 0x%x\r\n", pHandleData->s, pIoData);
    if(pIoData == NULL)
    {
    ATLTRACE("申请IO失败! \r\n");
    return;
    } {
    CAutoLock LockList(&m_ListIoInUsecs, "HandleIo");
    pHandleData->ListIoData.push_back(pIoData);
    }
    ATLTRACE("申请读节点,地址:0x%x \r\n", pIoData); buf.buf = pIoData->szBuf;
    buf.len = MAX_BUF;
    pIoData->byOperType = OPER_READ;
    //增加接收请求计数
    nRet = WSARecvFrom(pHandleData->s, &buf, 1, NULL, &dwFlag, (SOCKADDR*)&(pIoData->RemoteAddr), &nLen, &(pIoData->ol), NULL);
    if(nRet == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
    {
    ATLTRACE("Recv request failed ! HandleIoData errorcode: %d \r\n", WSAGetLastError());
    {
    CAutoLock LockList(&m_ListIoInUsecs, "err recv");
    FreeIoData(pIoData, pHandleData);
    }

    return;
    }
    InterlockedIncrement(&pHandleData->dwRecvOutstandingCount);
    //向数据队列中加入数据
    {
    CAutoLock LockDeque(&m_Dequecs, "HandleIo  DequeData");
    m_dequeData.push_back(pData);
    } PostMessage(m_hMsgWnd, WM_GETDATA, 0, (LPARAM)this);//通知接收数据
    break;
    }
    case OPER_SEND:
    {
    //递减请求计数
    {
    CAutoLock LockList(&m_ListIoInUsecs, "HandleIo  Deque Data");
    FreeIoData(pIoData, pHandleData);
    InterlockedDecrement(&pHandleData->dwSendOutstandingCount);
    ATLTRACE("Release IOBuffer after Send  Sendcount: %d \r\n", pHandleData->dwSendOutstandingCount);
    }
    break;
    }
    default:
    break;
    }
    return;
    }帮我看看,在哪里出了问题!谢谢!!
      

  2.   

    本人因毕业离校..现低价出售电脑一台 
        电脑配置如下: 
    1.CPU:  AMD4000+ 2.内存:GelllG1667 3.硬盘:WD160G 4.主板:GMK8T890 5.显卡:七彩虹8400GS 6.外带摄像头,音响,键盘,鼠标 7.卖主机送显示器{纯平显示器}   有意者请拨:13419523734 或QQ:450445043       或直接到学生公寓3栋625看电脑..... 
      

  3.   

    主要是 系统DLL 弹出错误框,也不知道这种情况如何调试,各位,给点调试方法也好啊!
      

  4.   

       楼主可以利用任务管理器里面看看资源的占用情况,在多线程编程中,有时资源占用大的时候,系统本身调度不过来就可能莫名其妙地出现系统的动态库报错的。这样可以先确定是不是系统的资源不足的问题。
       有个重要的问题要提醒楼主的是在多线程编程中,若使用的系统windows平台,那么一个进程能开辟的最大内存在2G左右,而Linux中好像是没有这个限制的。楼主的程序应该是单进程多线程的,所以也必须考虑内存限制。
       以上仅是我编程中一些经验希望对你有用的!
      

  5.   

    buf.buf = pIoData->szBuf;//这一块内存是unpaged的
                buf.len = MAX_BUF;
    是不是等待接收的套接字太多,而真正接收的数据很少,使得大量unpaged的内存被使用,导致的问题。
    楼主看看这一块内存是否被释放了。
    1。只发起连接,但客户端不发送数据,直至处理异常,看看是否也会出现同样的问题,验证我上面说的情况是否属实。
    2。监控内存变化,是否只增不减。
      

  6.   


        while(1)
        {
        //写到这里
        DWORD dwTrans = 0;
        DWORD dwKey = 0;
        PER_HANDLE_DATA *pHandleData = NULL;
        PER_IO_DATA *pIoData = NULL;
        BOOL bRet = FALSE;        bRet = GetQueuedCompletionStatus(hIOCP, &dwTrans, &dwKey, (LPOVERLAPPED*)&pIoData, INFINITE);   // 你这下面都释放掉了,你也不复位,不死才怪了.   }
      

  7.   

    if(pIoData == NULL) //关闭套接字引起
                    {
                        ATLTRACE("---关闭套接字引起---\r\n");
                        CAutoLock(&(pThis->m_ListIoInUsecs), "Receivethread");
                        pThis->FreeIoData(pIoData, pHandleData);
                        continue;
                    }
      

  8.   

    还有其他地方,自己检查一下吧,最好在while循环里加判断pIoData,pHandleData是否为空
    其他地方(比如内存分配,socket创建是否成功等等)也检查一下
      

  9.   

    一般IOCP内存错误可能是内存分不出来了,调试方法的话,使用windbg,崩溃时可以把dump信息贴上来
      

  10.   

    特殊情况,给自己看的, 不好意思//---- 运算符标识名 -----   --------- 优先级 ---------------   --- 说明 ---
    const int Add        = 10;  const int ADDPriority        = 4;   // +
    const int Subtract   = 9;   const int SubtractPriority   = 4;   // -
    const int Less       = 8;   const int LessPriority       = 3;   // <
    const int LessEqual  = 7;   const int LessEqualPriority  = 3;   // <=
    const int Great      = 6;   const int GreatPriority      = 3;   // >
    const int GreatEqual = 5;   const int GreatEqualPriority = 3;   // >=
    const int EqualEqual = 4;   const int EqualEqualPriority = 3;   // ==
    const int And        = 3;   const int AndPriority        = 2;   // &&
    const int OR         = 2;   const int ORPriority         = 2;   // ||
    const int Equal      = 1;   const int EqualPriority      = 1;   // =
    //---------------------------------------------------------------------------
      

  11.   

    给自己看的,不麻烦大家了.
    //---- 运算符标识名 -----   --------- 优先级 ---------------   --- 说明 ---
    const int Add        = 10;  const int ADDPriority        = 4;   // +
    const int Subtract   = 9;   const int SubtractPriority   = 4;   // -
    const int Less       = 8;   const int LessPriority       = 3;   // <
    const int LessEqual  = 7;   const int LessEqualPriority  = 3;   // <=
    const int Great      = 6;   const int GreatPriority      = 3;   // >
    const int GreatEqual = 5;   const int GreatEqualPriority = 3;   // >=
    const int EqualEqual = 4;   const int EqualEqualPriority = 3;   // ==
    const int And        = 3;   const int AndPriority        = 2;   // &&
    const int OR         = 2;   const int ORPriority         = 2;   // ||
    const int Equal      = 1;   const int EqualPriority      = 1;   // =
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    //     运算符标识名                   优先级                   运算符 
    //---------------------------------------------------------------------------
    const int Add        = 10;  const int ADDPriority        = 4;  // +
    const int Subtract   = 9;   const int SubtractPriority   = 4;  // -
    //---------------------------------------------------------------------------
    const int Less       = 8;   const int LessPriority       = 3;  // <
    const int LessEqual  = 7;   const int LessEqualPriority  = 3;  // <=
    const int Great      = 6;   const int GreatPriority      = 3;  // >
    const int GreatEqual = 5;   const int GreatEqualPriority = 3;  // >=
    const int EqualEqual = 4;   const int EqualEqualPriority = 3;  // ==
    //---------------------------------------------------------------------------
    const int And        = 3;   const int AndPriority        = 2;  // &&
    const int OR         = 2;   const int ORPriority         = 2;  // ||
    //---------------------------------------------------------------------------
    const int Equal      = 1;   const int EqualPriority      = 1;  // =
    //---------------------------------------------------------------------------
      

  12.   

    enum ExpressionItemType
    {
        enumInvalid  =  0,  // 0:无效值
        enumOperator =  1,  // 1:operator 运算符项
        enumIntParam =  2,  // 2:intParam 参数项, 其值为int
        enumSzParam  =  3,  // 3:szParam  参数项, 其值为字符串
        //enumFunction = 9  // 9:function 参数项,
    };
    //Expression= " (%sUserType@ == %s1@) && (%sMSISDN@ > %s138@) && KDJ || %sabc@ "struct/class ExpressionItem
    {
        int iItemType;      // 1:operator, 2:intParam, 3:szParam, ... 9:function;
        
        // 1:operator
        int iOperType;      // 标识运算符 (>, >=, <=, <, ==, =, ||, &&, !)
        int iOperPriority;  // 1, 2, 3, 11, 112, 113, 1113; <--每深入一层括号,优先级前面加1。        // 2:intParam (或运算过程中的 中间值)
        int iParam;    // 3:szParam  (或中间值)
        char szParam[48];   // 表达式的字符串项: "MSISDN@", 
    };
      

  13.   

    这问题让人崩溃,我也遇到了这问题,出错时调用call stack看看。或者用BoundsChecker检查
      

  14.   

    兄弟,我今天仿佛见到了阳光,我在一段代码上看到这样一段话:
    /*
    * Comments about bug in OnWrite() added 051227.. 

    * This BUG was difficult to find. The bug was found after  6 hours of 
    * extensive debugging  with several debug tools as Rational Test Suite, 
    * SoftICe , VC++ DEBUG, GLOWCODE, etc.  I Found that in some rarely bizarre 
    * cases  (when a client rapidly disconnect & reconnect, etc..)  we get an 
    * access violation , etc. First of all we had one ReleaseClientContext to many 
    * in OnWrite() which caused access violation. Second when I remove it, I found 
    * that sometimes the client specific data (e.g. ClientContext) does not removed/relesed 
    * from memory, even if the client is disconnected. The reason in not 
    * intuitive and do not ask me how I figured it out. The problem occurs 
    * when an send is not ordered (see http://www.codeproject.com/internet/iocp_server_client.asp, 
    * section "3.6.2 The package reordering problem" for more information ) and 
    * we call the function GetNextSendBuffer(pContext,pOverlapBuff); (above) in Onwrite(..), 
    * to get the correct buffer to process. At exactly this point the remote client disconnects
    * and this leads to the bug. Now I got tired of explaining this hassling stuff, so lets 
    * go to the business the fix is below.. 
    这段解释和我的情况有点相同,不知和你的情况怎样?
      

  15.   

    1,UDP 其实没必要 IOCP
    2,对于 IOCP 线程的理解,以及内存释放的控制,要求还是挺高的
    楼主的错误就跟 0xC0000005 一样的,非法访问内存,检查初始化分配和释放吧