这个函数用于获取计算机上首个未使用的 TCP 端口以便程序使用。有时候我们并不需要一个固定的端口来提供服务,通过这个函数,我们就可以找到一个可用的端口了。这个函数如果返回 0 ,则没有任何可用的端口(几率几乎为 0 吧?),同样的方法也可以用于获取可用的 UDP 端口,换个函数而已。
uses IpRtrMib, Iphlpapi, winsock;
function GetFirstUnusedTcpPort(ADefPort: Word): Word;
var
ATables: PMIB_TCPTABLE;
ASize: DWORD;
Addr: TInAddr;
I: Integer;
AUsedPorts: array [0 .. 8191] of Byte;
begin
ASize := 0;
Result := 0; // 无效
if ADefPort=0 then
ADefPort:=GetCurrentProcessId;
if GetTcpTable(nil, ASize, True) = ERROR_INSUFFICIENT_BUFFER then
begin
GetMem(ATables, ASize);
try
if GetTcpTable(ATables, ASize, True) = NO_ERROR then
begin
FillChar(AUsedPorts, 8192, 0);
for I := 0 to ATables.dwNumEntries - 1 do
begin
ASize := ntohs(ATables.table[I].dwLocalPort);
AUsedPorts[ASize shr 3] := AUsedPorts[ASize shr 3] or
(1 shl (ASize and $7));
end;
for Result := ADefPort to 65535 do
begin
if (AUsedPorts[Result shr 3] and (1 shl (Result and $7))) = 0 then
Exit;
end;
for I := 1 to Result-1 do
begin
if (AUsedPorts[Result shr 3] and (1 shl (Result and $7))) = 0 then
Exit;
end;
Result:=0;
end;
finally
FreeMem(ATables);
end;
end;
end;参数是默认的端口号,如果这个端口号没被占用,则会被返回,如果被占用了,则返回其它值。
