EnumProtocolsA 函数 (nspapi.h)

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

注释EnumProtocols 函数是 Windows 套接字 1.1 规范的特定于Microsoft扩展。 此函数已过时。 为方便 Windows Sockets 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 [仅限桌面应用]
目标平台 窗户
标头 nspapi.h
Mswsock.lib
DLL Mswsock.dll

另请参阅

GetAddressByName

PROTOCOL_INFO

Winsock 函数

Winsock 参考