得到网络端口使用情况的两个函数

本文提供了一种使用Delphi枚举TCP和UDP占用端口的方法。通过调用网络库实现获取正在使用的端口列表,并提供了测试端口是否被占用的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

{*******************************************************}
{                                                       }
{       单元名: uGetExistPost.pas                       }
{                                                       }
{       作  者: Kook (狂迷)                             }
{                                                       }
{       版权所有 (C) 2006 列举已占用的网络端口          }
{                                                       }
{*******************************************************}

{*******************************************************
 版本 :
 目的及主要功能 :
 创建日期 : 2006-7-2 22:00:49

 版本 :
 修改日期 :
 修改者 :
 修改内容 :

*******************************************************}

unit uGetExistPost;

interface
uses
  Windows, SysUtils, WinSock;
type
  TProtocols = (gpTCP, gpUDP);
  TCallBack = procedure(const APort: integer) of object;

  //  功能描述:得到已用端口列表
function ListExistPort(GetPost: TCallBack; const AProto: TProtocols): Boolean;

//  功能描述:测试端口是否正被占用
function PortExist(const APort: integer; const AProto: TProtocols): Boolean;

implementation

type
  TAsnOctetString = record
    stream: pByte;
    length: Cardinal;
    dynamic: Boolean;
  end;

  TAsnObjectIdentifier = record
    idLength: Cardinal;
    ids: Pointer;
  end;
  pAsnObjectIdentifier = ^TAsnObjectIdentifier;

  TAsnObjectSyntax = record
    case asnType: Byte of
      0: (number: LongInt);
      1: (unsigned32: Cardinal);
      2: (counter64: Int64);
      3: (AsnString: TAsnOctetString);
      4: (bits: TAsnOctetString);
      5: (AsnObject: TAsnObjectIdentifier);
      7: (sequence: TAsnOctetString);
      8: (address: TAsnOctetString);
      9: (counter: Cardinal);
      10: (gauge: Cardinal);
      11: (ticks: Cardinal);
      12: (arbitrary: TAsnOctetString);
  end;

  TRFC1157VarBind = record
    name: TAsnObjectIdentifier;
    value: TAsnObjectSyntax;
  end;
  pRFC1157VarBind = ^TRFC1157VarBind;

  TRFC1157VarBindList = record
    list: pRFC1157VarBind;
    len: DWord
  end;
  pRFC1157VarBindList = ^TRFC1157VarBindList;

  TSnmpExtensionInit = function(dwTimeZeroReference: DWord;
    hPollForTrapEvent: PHandle;
    pFirstSupportedRegion: pAsnObjectIdentifier
    ): Boolean; stdcall;

  TSnmpExtensionQuery = function(requestType: Byte;
    variableBindings: pRFC1157VarBindList;
    errorStatus: pLongInt;
    errorIndex: pLongInt
    ): Boolean; stdcall;

const
  tcpidentifiers: array[0..9] of Cardinal = (1, 3, 6, 1, 2, 1, 6, 13, 1, 1);
  udpidentifiers: array[0..9] of Cardinal = (1, 3, 6, 1, 2, 1, 7, 5, 1, 1);

var
  hInetLib: THandle;
  MySnmpExtensionInit: TSnmpExtensionInit;
  MySnmpExtensionQuery: TSnmpExtensionQuery;
  wsaData: TWSAData;
  hTrapEvent: THandle;
  hIdentifier: TAsnObjectIdentifier;
  bindList: TRFC1157VarBindList;
  bindEntry: TRFC1157VarBind;
  errorStatus, errorIndex: LongInt;

  {-------------------------------------------------------------------------------
    函 数 名:LoadInetMibEntryPoints
    功能描述:动态加载DLL
    输入参数:无
    返 回 值: Boolean
    创建日期:2006.07.02 21:18
    修改日期:2006.
    作    者:OopsWare
    附加说明:
  -------------------------------------------------------------------------------}

function LoadInetMibEntryPoints: Boolean;
begin
  Result := False;
  hInetLib := LoadLibrary('inetmib1.dll');
  if hInetLib = 0 then Exit;
  @MySnmpExtensionInit := GetProcAddress(hInetLib, 'SnmpExtensionInit');
  if @MySnmpExtensionInit = nil then Exit;
  @MySnmpExtensionQuery := GetProcAddress(hInetLib, 'SnmpExtensionQuery');
  if @MySnmpExtensionQuery = nil then Exit;
  Result := True;
end;

function FreeInetMibEntryPoints: Boolean;
begin
  Result := FreeLibrary(hInetLib);
end;

{-------------------------------------------------------------------------------
  函 数 名:ListExistPort
  功能描述:得到已用端口列表
  输入参数:GetPost: TCallBack; const AProto: TProtocols
  返 回 值: Boolean
  创建日期:2006.07.02 22:46
  修改日期:2006.
  作    者:Kook
  附加说明:通过回调函数GetPost得到已用端口列表
-------------------------------------------------------------------------------}

function ListExistPort(GetPost: TCallBack; const AProto: TProtocols): Boolean;
begin
  Result := False;
  if not Assigned(GetPost) then
  begin
    raise ERangeError.Create('无回调函数!');
    Exit;
  end;

  if WSAStartup($0101, wsaData) <> 0 then
  begin
    raise ERangeError.Create('初始化 Winsock 异常!');
    Exit;
  end;

  if not LoadInetMibEntryPoints then
  begin
    raise ERangeError.Create('载入网络库异常!');
    Exit;
  end;
  try
    if not MySnmpExtensionInit(GetCurrentTime, @hTrapEvent, @hIdentifier) then
    begin
      raise ERangeError.Create('初始化网络库异常!');
      Exit;
    end;

    bindEntry.name.idLength := $0A;

    case AProto of
      gpTCP:
        bindEntry.name.ids := @(tcpidentifiers[0]);
      gpUDP:
        bindEntry.name.ids := @(udpidentifiers[0]);
    end;

    bindList.list := @bindEntry;
    bindList.len := 1;

    while True do
    begin
      if not MySnmpExtensionQuery($A1, @bindList, @errorStatus, @errorIndex)
        then
        Exit;

      if bindEntry.name.idLength < $0A then break;

      if (pDWord(Integer(bindEntry.name.ids) + 9 * Sizeof(Cardinal)))^ = 3 then
        GetPost(bindEntry.value.number); //回调输出
    end;
  finally
    FreeInetMibEntryPoints;
  end;
end;

{-------------------------------------------------------------------------------
  函 数 名:PortExist
  功能描述:测试端口是否正被占用
  输入参数:const APort: integer; 端口号
            const AProto: TProtocols 协议
  返 回 值: Boolean  //TRUE = 已被占用; FALSE = 未被占用
  创建日期:2006.07.02 22:35
  修改日期:2006.
  作    者:Kook
  附加说明:
-------------------------------------------------------------------------------}

function PortExist(const APort: integer; const AProto: TProtocols): Boolean;
begin
  Result := False;

  if WSAStartup($0101, wsaData) <> 0 then
  begin
    raise ERangeError.Create('初始化 Winsock 异常!');
    Exit;
  end;

  if not LoadInetMibEntryPoints then
  begin
    raise ERangeError.Create('载入网络库异常!');
    Exit;
  end;
  try
    if not MySnmpExtensionInit(GetCurrentTime, @hTrapEvent, @hIdentifier) then
    begin
      raise ERangeError.Create('初始化网络库异常!');
      Exit;
    end;

    bindEntry.name.idLength := $0A;

    case AProto of
      gpTCP:
        bindEntry.name.ids := @(tcpidentifiers[0]);
      gpUDP:
        bindEntry.name.ids := @(udpidentifiers[0]);
    end;

    bindList.list := @bindEntry;
    bindList.len := 1;

    while True do
    begin
      if not MySnmpExtensionQuery($A1, @bindList, @errorStatus, @errorIndex)
        then
        Exit;

      if bindEntry.name.idLength < $0A then break;

      if bindEntry.value.number = APort then
      begin
        Result := True;
        Break;
      end;
    end;
  finally
    FreeInetMibEntryPoints;
  end;
end;
end.

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值