问题
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