1. 程式人生 > >WSADuplicateSocket、WSASocket失敗,錯誤碼為WSAEINVAL(10022)

WSADuplicateSocket、WSASocket失敗,錯誤碼為WSAEINVAL(10022)

PS:最近又發現一種無法複用套接字的情況,修改一下。2011/10/11 16:24

一、失敗的原因:

1、MS的解釋

    http://support.microsoft.com/kb/216603/en-us

2、目標程序和當前程序不在同一個session內

3、當前程序許可權比目標程序低

    WSADuplicateSocket內部會呼叫OpenProcess開啟目標程序的控制代碼,如果當前程序許可權較低,將會導致失敗,最終返回10022.

4、套接字的接收緩衝區大小不是預設值,且大於等於65536。

    這種情況會導致WSADuplicateSocket失敗,或者WSADuplicateSocket成功但WSASocket失敗。

二、解決方案:

1、第一種情況,攔截WSASocket, WSPSocket, WSAConnect,將WSAPROTOCOL_INFOW的dwServiceFlages1欄位進行如下處理:

    WSAPROTOCOL_INFOW lpProtocolInfo;

    lpProtocolInfo.dwServiceFlages1 &= ~XP1_QOS_SUPPORTED。

    以上程式碼防止當前程序建立QOS-enable套接字,保證WSADuplicateSocket成功。

2、第二種情況,不懂。

3、攔截OpenProcess,在內部返回目標程序的控制代碼。如何得到目標程序控制代碼是個難點。不過目標程序往往是自己寫,所以可以通過訊息機制讓目標程序呼叫DuplicateHandle返回它的控制代碼。

4、設定套接字的接收緩衝區時,大小小於65536即可。

    這個情況是遨遊的工程師在一段原始碼的註釋中發現的,原始碼地址:http://www.oschina.net/code/explore/cygwin-1.7.7-1/winsup/cygwin/net.cc。只有以下三個條件同時成立時,接收緩衝區的大小才會導致客戶端進行套接字複用時失敗:

    a. 服務端和客戶端處於不同機器;

    b. 客戶端已經收到一部分資料時;

    c. xp系統。