0

这是我的代码...

procedure TMainForm.tsConnect(AContext: TIdContext);
var
  s, INstr, adr:string;
  port: Integer;
begin
  with TMyContext(AContext) do
  begin
    Con := Now;
    if (Connection.Socket <> nil) then
      IP :=Connection.Socket.Binding.PeerIP;
    port:=Connection.Socket.Binding.PeerPort;
    s:=IntToStr(Connection.Socket.Binding.PeerPort);
    TIdStack.IncUsage();
    try
      adr:= GStack.HostName;
    finally
      TIdStack.DecUsage;
    end;

    INstr := Connection.IOHandler.ReadLn;
    Nick := INstr;

    if Nick <> '' then
    begin
      memo1.Lines.Add('Opened  <'+Nick + '>  '+adr+' '+IP+':'+s+'      '+DAteTimeToStr(now));
      //SendNicks;
    end else
    begin
      Connection.IOHandler.WriteLn('No Nick provided! Goodbye.');
      Connection.Disconnect;
    end;
  end;
end;

GStack.HostName 给出我的服务器的名称,如何获取客户端主机名?

4

1 回答 1

3

用于TIdStack.HostByAddress()获取客户端的远程主机名,例如:

adr := GStack.HostByAddress(IP);

话虽如此,您不需要调用TIdStack.IncUsage()andTIdStack.DecUsage()因为TIdTCPServer分别在其构造函数和析构函数中为您处理。但更重要的是,您对 的直接访问TMemo不是线程安全的。请记住,这TIdTCPServer是一个多线程组件。OnConnect事件(and OnDisconnectand在工作线程中运行,而OnExecute不是在主线程中运行。UI 访问必须在主线程中完成。

尝试这个:

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;

或者:

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;
于 2013-05-17T22:10:48.753 回答