zoukankan      html  css  js  c++  java
  • 使用WSAIoctl获取AcceptEx,Connectex,Getacceptexsockaddrs函数指针

    运行WinNT和Win2000的系统上,这些APIs在Microsoft提供的DLL(mswsock.dll)里实现,可以通过链接mswsock.lib或者通过WSAioctl的SIO_GET_EXTENSION_FUNCTION_POINTER操作动态调用这些扩展APIs.

    未获取函数指针就调用函数(如直接连接mswsock.lib并直接调用AcceptEx)的消耗是很大的,因为AcceptEx 实际上是存在于Winsock2结构体系之外的。每次应用程序常试在服务提供层上(mswsock之上)调用AcceptEx时,都要先通过WSAIoctl获取该函数指针。如果要避免这个很影响性能的操作,应用程序最好是直接从服务提供层通过WSAIoctl先获取这些APIs的指针。

    需要注意的是,通过WSAIoctl获取AcceptEx函数指针时,只需要传递给WSAIoctl一个有效的SOCKET即可,该Socket的类型不会影响获取的AcceptEx函数指针。

    同理可以获取Connectex与GetAcceptExSockaddrs函数指针。

    代码如下:

    typedef BOOL (WINAPI *AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED);
    typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const struct sockaddr *, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED);
    typedef void (WINAPI *GetAcceptExSockaddrsPtr)(PVOID, DWORD, DWORD, DWORD, LPSOCKADDR *, LPINT, LPSOCKADDR *, LPINT);
    
    
    struct win32_extension_fns {
    	AcceptExPtr AcceptEx;
    	ConnectExPtr ConnectEx;
    	GetAcceptExSockaddrsPtr GetAcceptExSockaddrs;
    };
    
    
    #ifndef WSAID_ACCEPTEX
    #define WSAID_ACCEPTEX 
    	{0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
    #endif
    #ifndef WSAID_CONNECTEX
    #define WSAID_CONNECTEX 
    	{0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}
    #endif
    #ifndef WSAID_GETACCEPTEXSOCKADDRS
    #define WSAID_GETACCEPTEXSOCKADDRS 
    	{0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
    #endif
    
    
    
    
    void * get_extension_function(SOCKET s, const GUID *which_fn)
    {
    	void *ptr = NULL;
    	DWORD bytes=0;
    	WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
    	    (GUID*)which_fn, sizeof(*which_fn),
    	    &ptr, sizeof(ptr),
    	    &bytes, NULL, NULL);
    
    	return ptr;
    }
    

      调用:

    const GUID acceptex = WSAID_ACCEPTEX;
    	const GUID connectex = WSAID_CONNECTEX;
    	const GUID getacceptexsockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
    	SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    	if (s == INVALID_SOCKET)
    		return;
    	ext->AcceptEx = (AcceptExPtr)get_extension_function(s, &acceptex);
    	ext->ConnectEx = (ConnectExPtr)get_extension_function(s, &connectex);
    	ext->GetAcceptExSockaddrs = (GetAcceptExSockaddrsPtr)get_extension_function(s,&getacceptexsockaddrs);
    	closesocket(s);
    

      

  • 相关阅读:
    【转】解决在Android设备播放音频与其他应用重音的问题,并监听耳机的控制按钮
    【转】wamp 3.0.6(apache 2.4.23) 403 forbidden 解决办法
    身份证第18位(校验码)的计算方法
    【转】Win10开机密码忘了?教你破解Win10开机密码
    【转】具透 | 你可能不知道,iOS 10 有一个中国「特供」的联网权限功能
    钉钉自定义机器人 发送文本 换行 无效果
    屏蔽右键+f12
    【转】理解WebKit和Chromium: JavaScript引擎简介
    第2章 排序 | 第10节 计数排序练习题 && 基数排序
    图像处理-深入探索插值操作
  • 原文地址:https://www.cnblogs.com/seer/p/4513959.html
Copyright © 2011-2022 走看看