enumProtocolsA 函数 (nspapi.h)

EnumProtocols 函数检索有关本地主机上处于活动状态的一组指定网络协议的信息。

注意EnumProtocols 函数是 Windows Sockets 1.1 规范的特定于 Microsoft 的扩展。 此函数已过时。 为方便 Windows 套接字 1.1 开发人员,我们提供了参考资料。 WSAEnumProtocols 函数在 Windows 套接字 2 中提供等效的功能。
 

语法

INT EnumProtocolsA(
  [in, optional] LPINT   lpiProtocols,
  [out]          LPVOID  lpProtocolBuffer,
  [in, out]      LPDWORD lpdwBufferLength
);

参数

[in, optional] lpiProtocols

指向以 null 结尾的协议标识符数组的指针。 EnumProtocols 函数检索有关此数组指定的协议的信息。

如果 lpiProtocolsNULL,则该函数将检索有关所有可用协议的信息。

定义了以下协议标识符值。

含义
IPPROTO_TCP
传输控制协议 (TCP) ,一种面向连接的流协议。
IPPROTO_UDP
用户数据报协议 (UDP) ,一种无连接数据报协议。
ISOPROTO_TP4
面向 ISO 连接的传输协议。
NSPROTO_IPX
Internet 数据包交换 (IPX) 协议(一种无连接数据报协议)。
NSPROTO_SPX
顺序数据包交换 (SPX) 协议,一种面向连接的流协议。
NSPROTO_SPXII
顺序数据包交换 (SPX) 协议版本 2,一种面向连接的流协议。

[out] lpProtocolBuffer

指向函数用 PROTOCOL_INFO 数据结构数组填充的缓冲区的指针。

[in, out] lpdwBufferLength

指向变量的指针,该变量在输入时指定 lpProtocolBuffer 指向的缓冲区的大小(以字节为单位)。

在输出时, 函数将此变量设置为检索所有请求的信息所需的最小缓冲区大小。 要使函数成功,缓冲区必须至少为此大小。

返回值

如果函数成功,则返回值是写入到 lpProtocolBuffer 指向的缓冲区PROTOCOL_INFO数据结构的数目。

如果函数失败,则返回值为 SOCKET_ERROR (-1) 。 若要获取扩展错误信息,请调用 GetLastError,这将返回以下扩展错误代码。

错误代码 含义
ERROR_INSUFFICIENT_BUFFER
lpProtocolBuffer 指向的缓冲区太小,无法接收所有相关PROTOCOL_INFO结构。 使用缓冲区至少与 *lpdwBufferLength 中返回的值一样大的缓冲区调用函数。

注解

在以下示例代码中, EnumProtocols 函数检索有关系统上可用的所有协议的信息。 然后,代码将更详细地检查每个协议。

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Nspapi.h>
#include <stdlib.h>
#include <stdio.h>


// Need to link with Ws2_32.lib and Mswsock.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")

int FindProtocol(BOOL Reliable, 
    BOOL MessageOriented, BOOL StreamOriented, 
    BOOL Connectionless, DWORD *ProtocolUsed); 

int __cdecl main(int argc, char **argv)
{
    WSADATA wsaData;

    int ProtocolError = SOCKET_ERROR;
    int iResult;
    
    BOOLEAN bReliable = FALSE;
    BOOLEAN bMessageOriented = FALSE;
    BOOLEAN bStreamOriented = TRUE;
    BOOLEAN bConnectionless = FALSE;
    DWORD *pProtocols = NULL;
    
    // Validate the parameters
    if (argc != 2) {
        printf("usage: %s servicename\n", argv[0]);
        return 1;
    }

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }
    
    ProtocolError = FindProtocol( bReliable, bMessageOriented,
        bStreamOriented, bConnectionless, pProtocols);
    if (ProtocolError == SOCKET_ERROR) {
        printf("Unable to find a protocol to support the parameters requested\n");
        return 1;
    }
    
    // Connect to the servicename ...    
    
    return 0;

}

#define MAX_PROTOCOLS 1024

int FindProtocol ( 
    BOOL Reliable, 
    BOOL MessageOriented, 
    BOOL StreamOriented, 
    BOOL Connectionless, 
    DWORD *ProtocolUsed 
    ) 
{ 
    // local variables 
    INT protocols[MAX_PROTOCOLS+1]; 
    BYTE buffer[2048]; 
    DWORD bytesRequired; 
    INT err; 
    PPROTOCOL_INFO protocolInfo; 
    INT protocolCount; 
    INT i; 
    DWORD protocolIndex; 
//    PCSADDR_INFO csaddrInfo; 
//    INT addressCount; 
//    SOCKET s; 
 
    // First look up the protocols installed on this computer. 
    // 
    bytesRequired = sizeof(buffer); 
    err = EnumProtocols( NULL, buffer, &bytesRequired ); 
    if ( err <= 0 ) 
        return SOCKET_ERROR; 
 
    // Walk through the available protocols and pick out the ones which 
    // support the desired characteristics. 
    // 
    protocolCount = err; 
    protocolInfo = (PPROTOCOL_INFO)buffer; 
 
    for ( i = 0, protocolIndex = 0; 
        i < protocolCount && protocolIndex < MAX_PROTOCOLS; 
        i++, protocolInfo++ ) { 
 
        // If connection-oriented support is requested, then check if 
        // supported by this protocol.  We assume here that connection- 
        // oriented support implies fully reliable service. 
        // 
 
        if ( Reliable ) { 
            // Check to see if the protocol is reliable.  It must 
            // guarantee both delivery of all data and the order in 
            // which the data arrives. 
            // 
            if ( (protocolInfo->dwServiceFlags & 
                    XP_GUARANTEED_DELIVERY) == 0 
                || 
                    (protocolInfo->dwServiceFlags & 
                    XP_GUARANTEED_ORDER) == 0 ) { 
 
                continue; 
            } 
 
            // Check to see that the protocol matches the stream/message 
            // characteristics requested. 
            // 
            if ( StreamOriented && 
                (protocolInfo->dwServiceFlags & XP_MESSAGE_ORIENTED) 
                    != 0 && 
                (protocolInfo->dwServiceFlags & XP_PSEUDO_STREAM) 
                     == 0 ) { 
                continue; 
            } 
 
            if ( MessageOriented && 
                    (protocolInfo->dwServiceFlags & XP_MESSAGE_ORIENTED) 
                              == 0 ) { 
                continue; 
            } 
 
        } 
        else if ( Connectionless ) { 
            // Make sure that this is a connectionless protocol. 
            // 
            if ( (protocolInfo->dwServiceFlags & XP_CONNECTIONLESS) 
                     != 0 ) 
                continue; 
        } 
 
        // This protocol fits all the criteria.  Add it to the list of 
        // protocols in which we're interested. 
        // 
        protocols[protocolIndex++] = protocolInfo->iProtocol; 
     }

     *ProtocolUsed = (INT) protocolIndex;
     return 0;
}

注意

nspapi.h 标头将 EnumProtocols 定义为别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将非特定编码别名与非非特定编码的代码混合使用可能会导致不匹配,从而导致编译或运行时错误。 有关详细信息,请参阅 函数原型的约定

要求

要求
最低受支持的客户端 Windows 2000 Professional [仅限桌面应用]
最低受支持的服务器 Windows 2000 Server [仅限桌面应用]
目标平台 Windows
标头 nspapi.h
Library Mswsock.lib
DLL Mswsock.dll

另请参阅

GetAddressByName

PROTOCOL_INFO

Winsock 函数

Winsock 参考