重疊ioWSARecv函數10014錯誤

這幾天心血來潮想自己再動手寫寫各個網絡io模型,以前只是寫過簡單的demo,實際工作中也沒用過,基本忘的也差不多了,現在想重新寫一下,沒想到還是有收穫的,這裏記錄其中一點。


今天寫到重疊io-完成例程模型,WSARecv函數一直返回10014錯誤,錯誤碼解釋是:
Bad address.
The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).
記得以前寫demo的時候遇到過這個錯誤是因爲flag參數直接傳了0,而不是傳了地址,不過這次這個參數我的確是傳了正確的地址,而且每個需要傳地址的參數都跟了一下,看起來都是正常的地址值,折騰了好久也沒有找到原因。


後來只能從頭來回憶是怎麼一步一步寫的這部分代碼,才突然想起來WSAOVERLAPPED的尾隨數據中,原來保存操作類型的成員是直接定義成Integer,而剛纔我把它改成了枚舉TOperationType = (opRecv, opSend),然後就試着又改成Integer,果然沒有10014錯誤了,搞到這裏就更納悶了,這兩種寫法唯一不同的就是這個字段的長度,一個是4字節,一個是一字節,整個帶尾隨數據的重疊結構大概是這樣定義的:
  TOperationType = (opRecv, opSend);
  TOverLappedInfo = record
    OverLap: WSAOVERLAPPED;
    Socket: TSocket;
    opType: TOperationType;
    WSAbuf: TWSABUF;
    Buf: array[0..1023] of Byte;
  end;
長度也就只能影響字節對齊,但是按這個結構來看,opType是Integer還是TOperationType 應該沒有差別,因爲TOverLappedInfo沒有packaged,無奈跟了一下代碼才發現WSAbuf的地址竟然不是在4字節邊界,心裏立馬有一萬隻小動物呼嘯而過,查看了一下WSAbuf結構,原來WSAbuf用了packaged,也就是相當於是1字節對齊,所以纔出現這種問題。


把WSAbuf調整到4字節邊界問題就都解決了,但是但是但是,爲毛WSAbuf不是在4字節邊界WSARecv就會10014,心裏再次有一萬隻小動物呼嘯而過,也就是說傳給WSARecv的這個結構的地址必須4字節對齊?到msdn上查了一下,沒仔細看,只是搜了一下關鍵次,沒有搜到Align之類的詞,到網上搜了一下,只搜到一個,說是WSAbuf參數需要對齊到32字節邊界,但是我這裏驗證的結果是只要是4字節對齊就ok了,對齊無非就是提高訪問效率,4字節應該就ok了,32字節不知道是怎麼得出來的,還望瞭解的朋友指點一下,今天就到這裏吧,太晚了,明天吧msdn仔細看下。


額。。昨晚提交的時候csdn博客在維護上傳不了,今天補上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章