Check remote port access using Delphi - Telnet sty

2019-05-29 07:46发布

问题:

I deploy my application in environments heavily stricken with firewalls. Frequently I find myself using Telnet to check if a port is open and accessible in the network. Now I would like to implement an equivalent functionality of the command, Telnet [domainname or ip] [port], in Delphi.

  1. Is it adequate that I just attempt to open and close a TCP/IP socket without sending or receiving any data?
  2. Is there any risk that I might crash the arbitrary application/service listening on the other end?

Here's my code:

function IsPortActive(AHost : string; APort : Word):boolean;
var IdTCPClient : TIdTCPClient;
begin
  IdTCPClient := TIdTCPClient.Create(nil);
  try
    try
      IdTCPClient.Host := AHost;
      IdTCPClient.Port := APort;
      IdTCPClient.Connect;

    except
      //Igonre exceptions
    end;

  finally
    result := IdTCPClient.Connected;
    IdTCPClient.Disconnect;
    FreeAndNil(IdTCPClient);
  end;
end;

回答1:

If you just want to check whether the port is open, then you can use this:

function IsPortActive(AHost : string; APort : Word): boolean;
var
  IdTCPClient : TIdTCPClient;
begin
  Result := False;
  try
    IdTCPClient := TIdTCPClient.Create(nil);
    try
      IdTCPClient.Host := AHost;
      IdTCPClient.Port := APort;
      IdTCPClient.Connect;
      Result := True;
    finally
      IdTCPClient.Free;
    end;
  except
    //Ignore exceptions
  end;
end;

But that only tells you if any server app has opened the port. If you want to make sure that YOUR server app opened the port, then you will have to actually communicate with the server and make sure its responses are what you are expecting. For this reason, many common server protocols provide an initial greeting so clients can identify the type of server they are connected to. You might consider adding a similar greeting to your server, if you are at liberty to make changes to your communication protocol.

Simply opening a connection to the server does not impose any risk of crashing the server, all it does is momentarily occupy a slot in the server's client list. However, if you actually send data to the server, and the server app you are connected to is not your app, then you do run a small risk if the server cannot handle arbitrary data that does not conform it its expected protocol. But that is pretty rare. Sending a small command is not uncommon and usually pretty safe, you will either get back a reply (which may be in a format that does not conform to your protocol, so just assume failure), or you may not get any reply at all (like if the server is waiting for more data, or simply is not designed to return a reply) in which case you can simply time out the reading and assume failure.