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

拜拜、爱过 提交于 2019-12-19 04:18:05

问题


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 IP who has that port listening.

Something similar to this code to test sockets but working in Inno Setup:

program pfinger;

uses sockets,errors;

Var
  Addr : TInetSockAddr;
  S : Longint;
  Sin,Sout : Text;
  Line : string;

begin
  Addr.sin_family:=AF_INET;
  { port 79 in network order }
  Addr.sin_port:=79 shl 8;
  { localhost : 127.0.0.1 in network order }
  Addr.sin_addr.s_addr:=((1 shl 24) or 127);
  S:=fpSocket(AF_INET,SOCK_STREAM,0);
  If Not Connect (S,ADDR,SIN,SOUT) Then
    begin
    Writeln ('Couldn''t connect to localhost');
    Writeln ('Socket error : ',strerror(SocketError));
    halt(1);
    end;
  rewrite (sout);
  reset(sin);
  writeln (sout,paramstr(1));
  flush(sout);
  while not eof(sin) do
    begin
    readln (Sin,line);
    writeln (line);
    end;
  fpShutdown(s,2);
  close (sin);
  close (sout);
end.

I've already tried other ways (Java code). But installer is starting slow, when I need to decompress JRE to run Java jar. I try to wrap my Java code, but don't know where/how find Pascal functions similar to Java.


回答1:


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?




回答2:


My go-to for checking open ports is the Nmap program.

An example command to probe address 192.168.200.133 on TCP port 3306 would be this:

nmap -sT -sV -Pn -n -p 3306 192.168.200.133

You can also scan an entire subnet by giving a CIDR range instead of an IP. As example, to scan for MySQL instances (TCP port 3306) on 192.168.200.1 - 192.168.200.254, you could do:

nmap -sT -sV -Pn -n -p 3306 192.168.200.0/24

^^ These examples were taken straight from https://securityblog.gr/1549/discover-open-mysql-ports/

Nmap is very commonly used on Unix/Linux, but has been ported to Windows, first in year 2000, currently supported on Win 7 or newer (including Server 2008). See https://nmap.org/book/inst-windows.html



来源:https://stackoverflow.com/questions/44057789/my-sql-server-discovery-on-lan-by-listening-port-inno-setup

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!