WSADuplicateSocket、WSASocket失败,错误码为WSAEINVAL(10022)

    技术2022-05-13  2

    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系统。


    最新回复(0)