My SQL server discovery on LAN by listening port (Inno Setup)

前端 未结 2 1729
春和景丽
春和景丽 2021-01-07 07:31

I need to search for an IP address with Listening Port to look up for others PC on LAN (try to discovery MySQL server) and get the results I

2条回答
  •  离开以前
    2021-01-07 07:45

    To check if a server is listening on a port, you can use Winsock OLE control:

    type
      TSocketState =
        (sckClosed, sckOpen, sckListening, sckConnectionPending, sckResolvingHost,
         sckHostResolved, sckConnecting, sckConnected, sckClosing, sckError);
    
    type
      TMsg = record
        hwnd: HWND;
        message: UINT;
        wParam: Longint;
        lParam: Longint;
        time: DWORD;
        pt: TPoint;
      end;
    
    const
      PM_REMOVE = 1;
    
    function PeekMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax,
      wRemoveMsg: UINT): BOOL; external 'PeekMessageA@user32.dll stdcall';
    function TranslateMessage(const lpMsg: TMsg): BOOL;
      external 'TranslateMessage@user32.dll stdcall';
    function DispatchMessage(const lpMsg: TMsg): Longint;
      external 'DispatchMessageA@user32.dll stdcall';
    
    procedure AppProcessMessage;
    var
      Msg: TMsg;
    begin
      while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
      begin
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      end;
    end;
    
    function CheckPort(Host: string; Port: Integer): Boolean;
    var
      Socket: Variant;
    begin
      Socket := CreateOleObject('MSWinsock.Winsock');
      Socket.RemoteHost := Host;
      Socket.RemotePort := Port;
      Socket.Connect;
    
      { Winsock requires message pumping }
      while not (Socket.State in [sckConnected, sckError]) do 
      begin
        AppProcessMessage;
      end;
    
      Result := (Socket.State = sckConnected);
    
      if Result then
      begin
        Log(Format('Port %d on %s is open', [Port, Host]));
      end
        else
      begin
        Log(Format('Port %d on %s is NOT open', [Port, Host]));
      end;
      Socket.Close;
    end;
    

    Note that the Winsock control requires message queue pumping. So you may need to disable wizard before running the check, to prevent user from messing with the form.


    Credits: The AppProcessMessage comes from How to execute 7zip without blocking the InnoSetup UI?

提交回复
热议问题