MySQL 通过侦听端口在 LAN 上发现服务器 (Inno Setup)

MySQL server discovery on LAN by listening port (Inno Setup)

我需要使用 Listening Port 搜索 IP address 以查找 LAN 上的其他 PC(尝试发现 MySQL 服务器)并获取结果 IP谁在监听那个端口。

与此代码类似的用于测试套接字但在 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.

我已经尝试过其他方法(Java 代码)。但是安装程序启动缓慢,当我需要将 JRE 解压缩到 运行 Java jar 时。我尝试包装我的 Java 代码,但不知道 where/how 找到类似于 Java.

的 Pascal 函数

要检查服务器是否正在侦听端口,您可以使用 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;

请注意,Winsock 控件需要消息队列抽取。因此,您可能需要在 运行 检查之前禁用向导,以防止用户弄乱表单。


致谢:AppProcessMessage 来自

我检查开放端口的首选是 Nmap 程序。

在 TCP 端口 3306 上探测地址 192.168.200.133 的示例命令如下:

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

您还可以通过提供 CIDR 范围而不是 IP 来扫描整个子网。例如,要在 192.168.200.1 - 192.168.200.254 上扫描 MySQL 个实例(TCP 端口 3306),您可以这样做:

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

^^ 这些示例直接取自 https://securityblog.gr/1549/discover-open-mysql-ports/

Nmap 在 Unix/Linux 上非常常用,但已移植到 Windows,首先是在 2000 年,目前支持 Win 7 或更高版本(包括 Server 2008)。参见 https://nmap.org/book/inst-windows.html