Use TIdStack.HostByAddress()
to get the client's remote hostname, eg:
adr := GStack.HostByAddress(IP);
With that said, you do not need to call TIdStack.IncUsage()
and TIdStack.DecUsage()
because TIdTCPServer
handles that for you in its constructor and destructor, respectively. But more importanly, your direct access of the TMemo
is not thread-safe. Remember that TIdTCPServer
is a multi-threaded component. The OnConnect
event (and OnDisconnect
and OnExecute
runs in a worker thread, not the main thread. UI access must be done in the main thread instead.
Try this:
procedure TMainForm.tsConnect(AContext: TIdContext);
var
INstr, adr: string;
port: Integer;
begin
with TMyContext(AContext) do
begin
Con := Now;
IP := Connection.Socket.Binding.PeerIP;
port := Connection.Socket.Binding.PeerPort;
adr := GStack.HostByAddress(IP);
INstr := Connection.IOHandler.ReadLn;
Nick := INstr;
if Nick <> '' then
begin
TThread.Synchronize(nil,
procedure
begin
memo1.Lines.Add('Opened <' + Nick + '> ' + adr + ' ' + IP + ':' + IntToStr(port) + ' ' + DateTimeToStr(Con));
end
);
//SendNicks;
end else
begin
Connection.IOHandler.WriteLn('No Nick provided! Goodbye.');
Connection.Disconnect;
end;
end;
end;
Alternatively:
uses
..., IdSync;
type
TMemoNotify = class(TIdNotify)
protected
FMsg: String;
procedure DoNotify; override;
end;
procedure TMemoNotify.DoNotify;
begin
MainForm.Memo1.Lines.Add(FMsg);
end;
procedure TMainForm.tsConnect(AContext: TIdContext);
var
INstr, adr: string;
port: Integer;
begin
with TMyContext(AContext) do
begin
Con := Now;
IP := Connection.Socket.Binding.PeerIP;
port := Connection.Socket.Binding.PeerPort;
adr := GStack.HostByAddress(IP);
INstr := Connection.IOHandler.ReadLn;
Nick := INstr;
if Nick <> '' then
begin
with TMemoNotify.Create do
begin
FMsg := 'Opened <' + Nick + '> ' + adr + ' ' + IP + ':' + IntToStr(port) + ' ' + DateTimeToStr(Con);
Notify;
end;
//SendNicks;
end else
begin
Connection.IOHandler.WriteLn('No Nick provided! Goodbye.');
Connection.Disconnect;
end;
end;
end;