IOCP代码瘫痪有关问题

求助:IOCP代码瘫痪问题?
我写了一个IOCP,当我在单机测试,本机即充当服务器,又充当客户端。客户端模拟上传文件,模拟方法是,每次上传8000字节到服务器,服务器反馈一个41字节的信息给客户端。客户端收到信息后,继续发送8000字节,循环4000次。这就是一次上传过程。当连续模拟5-6次后,上传流量开始减少,最后,服务器SafeArrayCreateVector失败,甚至连字符串分配、组件对象创建创建都返回空导致内存异常而崩溃。
  可是,当我将客户端和服务器在不同机器上运行,客户端上传或下载数据,客户端和服务器比较稳定。我想问的问题是,是不是ICOP本身的缺陷导致的这个问题,还是我的代码问题导致的该问题。给分100分,请各位专家解答!
  我的IOCP基本思路如下:
  1)定义PER_IO_OPERATION_DATA和_PER_HANDLE_DATA
C/C++ code
typedef struct
    {
    OVERLAPPED Overlapped;
    WSABUF DataBuf;
    char Buffer[MAX_BUFFER_SIZE];
    BYTE operType;
    DWORD BytesRecv;
    DWORD BytesLength;
    DWORD BytesPin;
    DWORD BytesFrom;
}PER_IO_OPERATION_DATA,*LPPER_IO_OPERATION_DATA;
typedef struct _PER_HANDLE_DATA
{
    SOCKET Socket;
    SOCKADDR_IN addressinfo;
    char parameters[256];
    HANDLE g_pUser;
    HANDLE g_pServer;
    DOUBLE RecentTime;
    LPPER_IO_OPERATION_DATA PerIoData;//服务器每个客户链接的WSARecv对应的PerIoData
    LPPER_IO_OPERATION_DATA wPerIoData;//服务器每个客户链接的WSASend对应的PerIoData
}PER_HANDLE_DATA,*LPPER_HANDLE_DATA;
2)ProcessIO关键代码:
   UINT WINAPI CServerSocket::ProcessIO(LPVOID lpParam)
{
     ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
     ....
     while(true)
     {
         if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,(PULONG_PTR)&PerHandleData,(LPOVERLAPPED*)&lpOverlapped,INFINITE))
         {
             if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
             {
                 PerIoData = (LPPER_IO_OPERATION_DATA)CONTAINING_RECORD(lpOverlapped,PER_IO_OPERATION_DATA,Overlapped);
                 if(PerHandleData==NULL) 
                 {
                     ::GlobalFree(PerIoData);
                     SetEvent(m_Tread);
                     return 0;
                 }
                 IsOk=VARIANT_FALSE;
                 if(PerHandleData->g_pUser!=NULL) 
                 {
                     m_pServer->Fire_OnClientQuit((INetUser*)PerHandleData->g_pUser);
                     CNetUsers*cUsers=(CNetUsers*)m_pServer->pUsers;
                     cUsers->RemoveUser((INetUser*)PerHandleData->g_pUser,&IsOk);
                     PerHandleData=NULL; 
                 }
                 continue;
             }
         }
         PerIoData = (LPPER_IO_OPERATION_DATA)CONTAINING_RECORD(lpOverlapped,PER_IO_OPERATION_DATA,Overlapped);
         if(PerHandleData==NULL) 
         {
             ::GlobalFree(PerIoData);
             SetEvent(m_Tread);
              ::CoUninitialize();
            return 0;
         }
         // 说明客户端已经退出
         if((BytesTransferred == 0)&&(PerIoData->operType==0))
         {
             IsOk=VARIANT_FALSE;
             if(PerHandleData->g_pUser!=NULL) 
             {
                 CNetUsers*cUsers=(CNetUsers*)m_pServer->pUsers;
                 m_pServer->Fire_OnClientQuit((INetUser*)PerHandleData->g_pUser);
                 cUsers->RemoveUser((INetUser*)PerHandleData->g_pUser,&IsOk);
             }
             continue;
         }
         if(PerIoData->operType==0)
         {
             PerIoData->BytesRecv+=BytesTransferred;
             if(PerIoData->BytesLength==0)
             {
                 if(PerIoData->BytesRecv<8)
                 {
                     ZeroMemory(&(PerIoData->Overlapped),sizeof(OVERLAPPED));
                     PerIoData->BytesPin+=BytesTransferred;
                     PerIoData->DataBuf.buf = PerIoData->Buffer+PerIoData->BytesPin;
                     PerIoData->DataBuf.len = MAX_BUFFER_SIZE-PerIoData->BytesPin;
                     WSARecv(PerHandleData->Socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL); 
                     continue;
                 }
                 char*buffer=(char*)PerIoData->Buffer+PerIoData->BytesFrom; //操作同一块内存区域
                 LONG BufferSize;
                 char*ca=(char*)&BufferSize;
                 memcpy(ca,buffer+4,4);
                 PerIoData->BytesLength=BufferSize+PACKAGE_HEADER;
             }
             bool IsValid=true;
             if(PerIoData->BytesRecv>=PerIoData->BytesLength)
             {
                int ValidPin=PerIoData->BytesPin+BytesTransferred;
                while(TRUE)
                {
                    char*buffer=(char*)PerIoData->Buffer+PerIoData->BytesFrom; //操作同一块内存区域
                    LONG BufferSize;
                    char*ca=(char*)&BufferSize;
                    memcpy(ca,buffer+4,4);
                    BufferSize+=PACKAGE_HEADER;
                    if(PerIoData->BytesFrom+BufferSize>ValidPin)
                    {
                        for(int k=PerIoData->BytesFrom;k<ValidPin;k++)
                        {
                            PerIoData->Buffer[k-PerIoData->BytesFrom]=PerIoData->Buffer[k];
                        }
                        PerIoData->BytesLength=BufferSize;
                        PerIoData->BytesRecv=ValidPin-PerIoData->BytesFrom;
                        PerIoData->BytesPin=PerIoData->BytesRecv;
                        PerIoData->BytesFrom=0;
                        break;
                    }
                    IDataPackage*pdr;
                    CDataPackage::_CreatorClass::CreateInstance(NULL, __uuidof(IDataPackage), (void**)&pdr);
                    BYTE*data=new BYTE[BufferSize];
                    if(data!=NULL)
                    {
                        memcpy(data,buffer,BufferSize);
                        CDataPackage*cPack=(CDataPackage*)pdr;
                        cPack->buffer=data;
                        IsValid=m_pServer->NotifyAcceptDataPackage(PerHandleData,pdr);
                        if(!IsValid)
                        {
                            pdr->Release();
                            break;
                        }
                    }
                    pdr->Release();
                    PerIoData->BytesFrom+=BufferSize;
                    BufferSize=PerIoData->BytesPin+BytesTransferred-PerIoData->BytesFrom;
                    if(BufferSize<PACKAGE_HEADER)
                    {
                        for(int k=0;k<BufferSize;k++)
                        {
                            PerIoData->Buffer[k]=PerIoData->Buffer[PerIoData->BytesFrom+k];
                        }
                        PerIoData->BytesLength=0;
                        PerIoData->BytesRecv=BufferSize;
                        PerIoData->BytesPin=BufferSize;
                        PerIoData->BytesFrom=0;
                        break;
                    }
                }
             }
             else
             {
                PerIoData->BytesPin+=BytesTransferred;
             }
             if(!IsValid) continue;
             // 取得数据并处理
             // 继续向 socket 投递WSARecv操作
             ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
             PerIoData->DataBuf.buf = PerIoData->Buffer+PerIoData->BytesPin;
             PerIoData->DataBuf.len = MAX_BUFFER_SIZE-PerIoData->BytesPin;
             WSARecv(PerHandleData->Socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);  
         }
         else if(PerIoData->operType==1)
         {
             m_pServer->sis.NotifyOutBytes(BytesTransferred);
             if(PerHandleData->g_pServer==m_pServer)
             {
                 if(BytesTransferred+PerIoData->BytesFrom<PerIoData->BytesLength)
                 {
                     ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
                     PerIoData->DataBuf.buf=PerIoData->Buffer+BytesTransferred+PerIoData->BytesFrom;
                     PerIoData->DataBuf.len=PerIoData->BytesLength-(BytesTransferred+PerIoData->BytesFrom);
                     PerIoData->BytesLength-=BytesTransferred;
                     PerIoData->BytesFrom+=BytesTransferred;
                     DWORD SendBytes;
                     WSASend(PerHandleData->Socket,&(PerIoData->DataBuf),1,&SendBytes,0,&(PerIoData->Overlapped),NULL);
                 }
                 else if(BytesTransferred>0)
                 {
                     INetUser*pUser=(INetUser*)PerHandleData->g_pUser;
                     CNetUser*cUser=(CNetUser*)pUser;
                     cUser->SendNextPackage();
                 }
             }
         }
     } 
     SetEvent(m_Tread);
     ::CoUninitialize();
     return 0;
}