За да проверите дали даден сървър слуша на порт, можете да използвате Winsock
OLE контрол
:
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 '[email protected] stdcall';
function TranslateMessage(const lpMsg: TMsg): BOOL;
external '[email protected] stdcall';
function DispatchMessage(const lpMsg: TMsg): Longint;
external '[email protected] 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
идва от Как да изпълня 7zip, без да блокирам потребителския интерфейс на InnoSetup?