WSAEnumProtocols函数的用法

      今天看到《windows网络编程》第二版里面有一个函数, 在第一次按照说明使用的时候没有成功. 以下是对应的技术说明.

  #include <winsock2.h>

  int WSAAPI WSAEnumProtocols ( LPINT lpdwProtocols,

  LPWSAPROTOCOL_INFO lpProtocolBuffer,

  LPDWORD lpdwBufferLength);

  lpdwProtocols:一个以NULL结尾的协议标识号数组。本参数可选;如果lpdwProtocols为 NULL,则返回所有可用协议的信息,否则的话只返回数组中所开列的协议信息。

  lpProtocolBuffer:一个用PROTOCOL_INFO结构填充的缓冲区。参见下文中对PROTOCOL_INFO结构的具体描述。

  lpdwBufferLength:输入时,存有传递给WSAEnumProtocols()函数的lpProtocolBuffer缓冲区长度。输出时,表示为获取所有信息需传递给WSAEnumProtocols()函数的缓冲区长度。本函数不能重复调用;传入的缓冲区必须足够大以能存放所有的元素。这个规定降低了该函数的复杂度。由于一个机器上装载的协议数目往往是很小的,所以并不会产生问题。

  返回值:

  若无错误发生,WSAEnumProtocols()返回协议的数目。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。

  错误代码:

  WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。

  WSAENETDOWN 网络子系统失效。

  WSAEINPROGRESS 一个阻塞WinSock调用正在进行。

  WSAEINVAL 参数中有非法值。

  WSAENOBUFS 缓冲区太小,无法保存所有PROTOCOL_INFO结构及其相关信息。传入的缓冲区大小至少应等于lpdwBufferLength中返回的值。

  通常需要两次调用WSAEnumProtocols()函数以获取特定的协议信息,第一次调用时指定lpdwProtocols为 NULL,调用肯定是失败的,但参数lpdwBufferLength包含了所以协议信息需要的缓冲区长度。我们知道了这个准确长度就可以进行第二次调用了!

      后来查找到原因, 因为我只做局部测试代码, 没有加载socket的DLL, 造成失败调用. 贴一段正确使用的代码:

//代码来源为:http://blog.csdn.net/chshji666666/article/details/6758260
#include <Winsock2.h>   
#include <stdio.h>   
#pragma comment(lib, "ws2_32.lib")   
  
void main(void)  
{  
     WSADATA wsaData;  
     WSAStartup( MAKEWORD( 2, 2 ), &wsaData );  
  
     LPWSAPROTOCOL_INFO info = NULL;  
     DWORD dwLen;  
  
     //因为info还未分配内存,第一次调用必定会失败,但能够得到dwLen的值   
     if (SOCKET_ERROR == WSAEnumProtocols(NULL, info, &dwLen))  
     {  
         int iErrorCode = GetLastError();  
         if (WSAENOBUFS != iErrorCode)  
         {  
             WSACleanup();  
             return;  
         }                  
     }  
  
     if (dwLen > 0)  
     {  
  
       //如果没有分配内存这一步,将会出错,只传递 &inof是没有用的,注意指针的用法   
        info = (LPWSAPROTOCOL_INFO)GlobalAlloc(GPTR, dwLen);  
         if (info == NULL)  
         {  
             printf("Allocate memory failed! ErrorCode is %d", GetLastError());  
             WSACleanup();  
             return;              
         }  
  
         //第二次调用   
         int iProtocolCounts = WSAEnumProtocols(NULL, info, &dwLen);      
         if (SOCKET_ERROR == iProtocolCounts)  
         {  
             printf("WSCEnumProtocols Error: %d", GetLastError());  
             GlobalFree(info);  
             WSACleanup();  
             return;      
         }  
  
         //打印本机安装的协议信息   
         for (int i=0; i<iProtocolCounts; i++)  
         {  
             printf("\ni=%d\nProtocolDescription:%s\n", i, info[i].szProtocol);              
         }  
  
         GlobalFree(info);      
     }  
     WSACleanup();  
}  


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值