未获取函数指针就调用函数(如直接连接mswsock.lib并直接调用AcceptEx)的消耗是很大的,因为AcceptEx 实际上是存在于Winsock2结构体系之外的。每次应用程序常试在服务提供层上(mswsock之上)调用AcceptEx时,都要先通过WSAIoctl获取该函数指针。如果要避免这个很影响性能的操作,应用程序最好是直接从服务提供层通过WSAIoctl先获取这些APIs的指针。
通过WSAIoctl获取AcceptEx函数指针时,只需要传递给WSAIoctl一个有效的SOCKET即可,该Socket的类型不会影响获取的AcceptEx函数指针,同理,其他的各种以EX后缀的扩展函数都可以这样使用了。
 
 我先声明了:
	LPFN_ACCEPTEX       lpAcceptEx;其他需要的参数我就略过去了
 然后
 DWORD nRet = WSAIoctl(                //此函数主要是用在 '改变套接字的模式' 上
        m_listen_socket,   
        SIO_GET_EXTENSION_FUNCTION_POINTER,    //第二个参数决定了WSAIoctl的不同用途
        &g_GUIDAcceptEx,   
        sizeof(g_GUIDAcceptEx),   
        &lpAcceptEx,  //作为输出缓冲区,以后就可以作为调用AcceptEx的指针 
        sizeof(lpAcceptEx),  
        &dwRet,NULL,NULL);
 nRet!=0.那么获取顺利,下一步,
 int bRet = lpAcceptEx(            //调用指针已可以使用
            m_listen_socket,  
            lp_io->socket,           //单IO数据结构
            lp_io->buf,   

            0,                     //该参数为0,函数接到连接后立即返回,不会接收数据
            sizeof(SOCKADDR_IN) + 16,  
            sizeof(SOCKADDR_IN) + 16,  
            &dwBytes,&lp_io->ol);
就是这样。简述:控制一个套接口的模式。
  #include <winsock2.h>
  int WSAAPI WSAIoctl(SOCKET s, DWORD
  dwIoControlCode, LPVOID lpvInBuffer, DWORD
  cbInBuffer, LPVOID lpvOutBuffer, DWORD
  cbOutBuffer, LPDWORD lpcbBytesReturned,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE
  lpCompletionRoutine);
  s:一个套接口的句柄。
  dwIoControlCode:将进行的操作的控制代码。
  lpvInBuffer:输入缓冲区的地址。
  cbInBuffer:输入缓冲区的大小。
  lpvOutBuffer:输出缓冲区的地址。
  cbOutBuffer:输出缓冲区的大小。
  lpcbBytesReturned:输出实际字节数的地址。
  lpOverlapped:WSAOVERLAPPED结构的地址。
  lpCompletionRoutine:一个指向操作结束后调用的例程指针。
  返回值:
  调用成功后,WSAIoctl ()函数返回0。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
  错误代码:
  WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
  WSAENETDOWN 网络子系统失效。
  WSAEINVAL cmd不是一个合法的命令;或者一个输入参数非法;或者命令对于该种类型的套接口不适用。
  WSAEINPROGRESS 在一个回调函数运行时调用了该函数。
  WSAENOTSOCK 描述字不是一个套接口。
  WSAEOPNOTSUPP 指定的ioctl命令无法实现,例如在SIO_SET_QOS或 SIO_SET_GROUP_QOS中指定的流描述无法实现。
  WSA_IO_PENDING 一个重叠操作被成功启动,过后将报告完成情况。
  WSAEWOULDBLOCK 套接口标志为非阻塞,且所需操作将产生阻塞。

使用WSAIoctl获取socket扩展函数(如AcceptEx)的指针的更多相关文章

  1. 使用WSAIoctl获取AcceptEx函数指针 [转]

    Winsock2的其他供应商不一定会实现AcceptEx函数.同样情况也包括的其他Microsoft的特定APIs如TransmitFile,GetAcceptExSockAddrs以及其他Micro ...

  2. 使用WSAIoctl获取AcceptEx,Connectex,Getacceptexsockaddrs函数指针

    运行WinNT和Win2000的系统上,这些APIs在Microsoft提供的DLL(mswsock.dll)里实现,可以通过链接mswsock.lib或者通过WSAioctl的SIO_GET_EXT ...

  3. 获取VB类模块成员函数指针(转)

    最近在做一些VB6.VBA的项目,被如何获取类模块中的函数指针这个问题所困扰,收集整理后,有2分资料值得收藏,特将关键部分留存,以备后续查找. 参照连接1:http://www.cnblogs.com ...

  4. windows socket扩展函数

    1.AcceptEx() AcceptEx()用于异步接收连接,可以取得客户程序发送的第一块数据. BOOL AcceptEx( _In_  SOCKET       sListenSocket,   ...

  5. 比isConnected()更靠谱的的获取socket实时连接状态!

    看到这个标题,预计非常多人会说用socket.isConnected()或者socket.isClosed()等方法来推断即可了,但其实这些方法都是訪问socket在内存驻留的状态,当socket和s ...

  6. 自动获取socket链接状态

    C# TcpClient在连接成功后无法检测连接状态,即使对方关闭了网络连接.以下扩展可检测连接状态: static class TcpClientEx { public static bool Is ...

  7. Qt 使用 lambda 表达式做为槽函数时为什么使用 QObject::sender() 获取到的发送信号对象指针为空?

    /*! Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; ...

  8. MFC获取各个窗体(体)之间的指针(对象)

    MFC在非常多的对话框操作中,我们常常要用到在一个对话框中调用还有一个对话框的函数或变量.能够用例如以下方法来解决.    HWND hWnd=::FindWindow(NULL,_T("S ...

  9. 通过网络socket获取对方 ip 和port

    int getpeername(int s, struct sockaddr *name, socklen_t *namelen);描述获取socket的对方地址struct sockaddr_in ...

随机推荐

  1. POJ 1201 Intervals (差分约束,最短路)

    题意: 有一个集合Z,其元素都是整整数,但是数量未知.现有n个约束,形如 [a,b]=c 表示整数区间[a,b]中有c个元素在Z中出现.问集合Z最小可能含多少个元素? 思路: 对于所给的区间 cnt[ ...

  2. HDU1010 Tempter of the Bone

    解题思路:相当经典的一题,回溯,具体细节处理见代码. #include<cstdio> #include<cstring> #include<algorithm> ...

  3. zoj 3690 Choosing number

    题意    就是说给你 N 个人站成一排,现在每个人都可以选择 1-M 中间的任意一个数字,相邻的两个人数字相同,则他必须是是 >  K 的  问方案总数: 方法    先求出递推式,然后用矩阵 ...

  4. ubuntu 上更新安装 openoffice.org3的过程

    方法一:手动安装1首先在“应用成程序--添加/删除”里卸载openoffice 2.4,可能openoffice.org 2.4 Draw因为关联而无法卸载,忽略,卸载其他几项.然后在中文官方网上下载 ...

  5. c++ 一个类使用另外一个类的变量或方法

    如:a.cpp 声明 int a=9; 要在b.cpp文件中使用变量 a extern int a; int b=1; cout<<a+b; 结果为10;

  6. Drupal如何更新注册表?

    Drupal的注册表是指registry和registry_file两个数据表.前一个表保存所有可用的类和接口以及它们所对应的文件,后一个表保存每个文件的hash码. 1. 将所有需要更新的文件都汇总 ...

  7. 【Java多线程】互斥

    Java多线程学习2——互斥 一.前言 在上一节 (http://www.cnblogs.com/lzhen/p/3917966.html) 中,通过实现Runnable接口,可以实现多线程中的资源的 ...

  8. linux中清除cache的方法

    在进行测试文件导入的时候,发现内存占用很大,如下所示: [root@python ~]# vmstat 1 -S M 3 procs -----------memory---------- ---sw ...

  9. 迭代的模块itertools

    itertools模块提供的全部是处理迭代功能的函数,他们的返回值不是list,而是迭代对象,只有在for循环的时候才会真正去计算. 使用迭代器的好处是在循环的时候才去取值,而直接返回值为list的结 ...

  10. Java 断点调试总结

    为了准备调试,你需要在代码中设置一个断点先,以便让调试器暂停执行允许你调试,否则,程序会从头执行到尾,你就没有机会调试了. 1. 条件断点 断点大家都比较熟悉,在Eclipse Java 编辑区的行头 ...