1. 程式人生 > >IOCP+UDP收包的時候:報0xC000000005,讀取0x00000010錯誤的問題

IOCP+UDP收包的時候:報0xC000000005,讀取0x00000010錯誤的問題

最近發現我那簡單得不再簡單的IOCP+UDP的底層出錯了,在大資料量的時候經常會報錯,並且清一色都是報的:報0xC000000005,讀取0x00000010錯誤.報錯之後,整個程式的堆疊就全部破壞掉了.從發現問題到今日問題的解決,已經過去了一個月的時間.
唯一能夠找到相關的資料只有:http://www.cppblog.com/HendricLee/archive/2008/07/29/57436.html
但是事實上,我的Overlapped都是複用的.因此,不大可能是此問題導致的.經過測試證明,也確實與此無關.
昨晚上又做了一系列的測試,結果到最後依舊是無果,百般無奈之下,只好問人,後面QQ好友Sagasarate告訴了我原委,我知道之後,只有兩種感覺:想哭,想撞牆.
至於為什麼,請看以下程式碼便知了.非常非常之低階的錯誤.
bool CUDPRecvSendThread::postRecvRequest(CUdpOverLappedRecv* pOverLappedRecv)
{
    ASSERT(pOverLappedRecv);
    
if (pOverLappedRecv == NULL) returnfalse;

    pOverLappedRecv
->Reset();

    DWORD dwBytesRecv 
=0;
    DWORD dwFlags 
=0;
    
int nSenderAddrSize =sizeof (sockaddr_in);

    
int rc =0;
    rc 
= ::WSARecvFrom(m_ServerSocket, pOverLappedRecv->GetWsaBuffer(), 1&dwBytesRecv, 
&dwFlags,
        pOverLappedRecv
->GetClientAddr(), &nSenderAddrSize,
        pOverLappedRecv
->GetOverlapped(), NULL);

    
if (rc == SOCKET_ERROR)
    
{
        DWORD dwErrorCode 
= ::WSAGetLastError();
        
if (dwErrorCode != WSA_IO_PENDING)
        
{
            
returnfalse;
        }

    }


    
returntrue;
}
請對照著MSDN看.
如果沒看出來,那我來告訴你是為什麼.
問題就在於WSARecvFrom的7個引數.
MSDN的描述:
lpFromlen[in, out]

A pointer to the size, in bytes, of the "from" buffer required only iflpFromis specified.

你會發現,這個引數是一個輸入輸出值.而WSARecvFrom投遞的是一個非同步的IOCP請求,故而,出了此方法(CUDPRecvSendThread::postRecvRequest)之後,nSenderAddrSize這個臨時變數就會被回收.不出事才怪了.
好吧,這事就是我幹出來的.今年竟是做一些腦殘的事情.腫麼了我這是.T_T
要解決這個問題,最好的辦法就是把nSenderAddrSize作為CUdpOverLappedRecv的成員變數儲存,這樣生命週期可以得以保證.
好吧,這件腦殘事就這麼結了.

posted on 2012-10-15 11:42 楊粼波 閱讀(1641) 評論(8)  編輯 收藏 引用 所屬分類: 原創文章網路程式設計C++Windows