LookupPersistentTcpPortReservation 函数 (iphlpapi.h)
LookupPersistentTcpPortReservation 函数为本地计算机上的连续 TCP 端口块查找永久性 TCP 端口预留的令牌。
语法
IPHLPAPI_DLL_LINKAGE ULONG LookupPersistentTcpPortReservation(
[in] USHORT StartPort,
[in] USHORT NumberOfPorts,
[out] PULONG64 Token
);
参数
[in] StartPort
按网络字节顺序排列的起始 TCP 端口号。
[in] NumberOfPorts
保留的 TCP 端口号数。
[out] Token
指向如果函数成功,则返回的端口预留令牌的指针。
返回值
如果函数成功,则返回值NO_ERROR。
如果函数失败,则返回值为以下错误代码之一。
返回代码 | 说明 |
---|---|
|
向该函数传递了无效参数。 如果在 StartPort 或NumberOfPorts 参数中传递零,则返回此错误。 |
|
找不到该元素。 如果找不到 由 StartPort 和 NumberOfPorts 参数指定的永久性端口块,则返回此错误。 |
|
使用 FormatMessage 获取返回错误的消息字符串。 |
注解
LookupPersistentTcpPortReservation 函数在 Windows Vista 及更高版本上定义。
LookupPersistentTcpPortReservation 函数用于查找 TCP 端口块的永久性预留的令牌。
TCP 端口块的持久预留是通过调用 CreatePersistentTcpPortReservation 函数创建的。 传递给 LookupPersistentTcpPortReservation 函数的 StartPort 或 NumberOfPorts 参数必须与 CreatePersistentTcpPortReservation 函数创建 TCP 端口块的永久性预留时使用的值匹配。
如果 LookupPersistentTcpPortReservation 函数成功,则返回的 Token 参数将指向 TCP 端口块的持久端口预留的令牌。 请注意,每次重启系统时,TCP 端口块的给定永久性预留的令牌可能会更改。
应用程序可以通过打开 TCP 套接字,然后调用 WSAIoctl 函数(指定 SIO_ASSOCIATE_PORT_RESERVATION IOCTL),并在对套接字上的 绑定 函数发出调用之前传递预留令牌,从而从 TCP 端口预留请求端口分配。
示例
以下示例查找永久性 TCP 端口预留,然后创建套接字并从端口预留分配端口。
#ifndef UNICODE
#define UNICODE
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h.>
#include <winsock2.h>
#include <mstcpip.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with iphlpapi.lib
#pragma comment(lib, "iphlpapi.lib")
// Need to link with Ws2_32.lib for Winsock functions
#pragma comment(lib, "ws2_32.lib")
int wmain(int argc, WCHAR **argv) {
// Declare and initialize variables
int startPort = 0; // host byte order
int numPorts = 0;
USHORT startPortns = 0; // Network byte order
ULONG64 resToken = {0};
unsigned long status = 0;
WSADATA wsaData = { 0 };
int iResult = 0;
SOCKET sock = INVALID_SOCKET;
int iFamily = AF_INET;
int iType = SOCK_STREAM;
int iProtocol = IPPROTO_TCP;
DWORD bytesReturned = 0;
// Note that the sockaddr_in struct works only with AF_INET not AF_INET6
// An application needs to use the sockaddr_in6 for AF_INET6
sockaddr_in service;
sockaddr_in sockName;
int nameLen = sizeof(sockName);
// Validate the parameters
if (argc != 3) {
wprintf(L"usage: %s <Starting Port> <Number of Ports>\n",
argv[0]);
wprintf(L"Look up a persistent TCP port reservation\n");
wprintf(L"Example usage:\n");
wprintf(L" %s 5000 20\n", argv[0]);
wprintf(L" where StartPort=5000 NumPorts=20");
return 1;
}
startPort = _wtoi(argv[1]);
if ( startPort < 0 || startPort> 65535) {
wprintf(L"Starting point must be either 0 or between 1 and 65,535\n");
return 1;
}
startPortns = htons((USHORT) startPort);
numPorts = _wtoi(argv[2]);
if (numPorts < 0) {
wprintf(L"Number of ports must be a positive number\n");
return 1;
}
status = LookupPersistentTcpPortReservation((USHORT) startPortns, (USHORT) numPorts, &resToken);
if( status != NO_ERROR )
{
wprintf(L"LookupPersistentTcpPortReservation returned error: %ld\n",
status);
return 1;
}
wprintf(L"LookupPersistentTcpPortReservation call succeeded\n");
wprintf(L" Token = %I64d\n", resToken);
// Comment out this block if you don't want to create a socket and associate it with the
// persistent reservation
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
wprintf(L"WSAStartup failed with error = %d\n", iResult);
return 1;
}
sock = socket(iFamily, iType, iProtocol);
if (sock == INVALID_SOCKET)
wprintf(L"socket function failed with error = %d\n", WSAGetLastError());
else {
wprintf(L"socket function succeeded\n");
iResult =
WSAIoctl(sock, SIO_ASSOCIATE_PORT_RESERVATION, (LPVOID) & resToken,
sizeof (ULONG64), NULL, 0, &bytesReturned, NULL, NULL);
if (iResult != 0) {
wprintf
(L"WSAIoctl(SIO_ASSOCIATE_PORT_RESERVATION) failed with error = %d\n",
WSAGetLastError());
} else {
wprintf(L"WSAIoctl(SIO_ASSOCIATE_PORT_RESERVATION) succeeded, bytesReturned = %u\n",
bytesReturned);
service.sin_family = AF_INET;
service.sin_addr.s_addr = INADDR_ANY;
service.sin_port = 0;
iResult = bind(sock, (SOCKADDR*) &service, sizeof(service) );
if (iResult == SOCKET_ERROR)
wprintf(L"bind failed with error = %d\n", WSAGetLastError());
else {
wprintf(L"bind succeeded\n");
iResult = getsockname(sock, (SOCKADDR*) &sockName, &nameLen);
if (iResult == SOCKET_ERROR)
wprintf(L"getsockname failed with error = %d\n", WSAGetLastError() );
else {
wprintf(L"getsockname succeeded\n");
wprintf(L"Port number allocated = %u\n", ntohs(sockName.sin_port) );
}
}
}
if (sock != INVALID_SOCKET) {
iResult = closesocket(sock);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error = %d\n", WSAGetLastError());
}
}
}
WSACleanup();
return 0;
}
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows Vista [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2008 [仅限桌面应用] |
目标平台 | Windows |
标头 | iphlpapi.h |
Library | Iphlpapi.lib |
DLL | Iphlpapi.dll |
另请参阅
CreatePersistentTcpPortReservation
CreatePersistentUdpPortReservation
DeletePersistentTcpPortReservation
DeletePersistentUdpPortReservation