Delphi 如何区分具有相同IP地址的多个客户端的连接?

Delphi 如何区分具有相同IP地址的多个客户端的连接?,delphi,indy10,Delphi,Indy10,如果客户端具有相同的IP和端口,那么识别它们的正确方法是什么?如果它们仅通过LAN连接,例如ip:198.162.1.1端口:2015。如果客户端具有相同的IP,如何使用其唯一ID检测哪个客户端已断开连接 TClient = class(TIdServerContext) private public PeerIP : String; procedure SendMessage(cIP, mStr : String); end; procedur

如果客户端具有相同的IP和端口,那么识别它们的正确方法是什么?如果它们仅通过LAN连接,例如ip:198.162.1.1端口:2015。如果客户端具有相同的IP,如何使用其唯一ID检测哪个客户端已断开连接

TClient = class(TIdServerContext)
  private
  public
    PeerIP      : String;     
    procedure SendMessage(cIP, mStr : String);
  end;

procedure TClient.SendMessage(cIP, mStr : String);
var
  Context: TClient;
  List: TList;
  I: Integer;
begin
  List := Form1.IdTCPServer1.Contexts.LockList;
  try
    for I := 0 to List.Count-1 do
    begin
      Context := TClient(List[I]);
      if (Context.PeerIP = cIP) then
      begin
        Connection.IOHandler.WriteLn(mStr);
        Break;
      end
    end;
  finally
    Form1.IdTCPServer1.Contexts.UnlockList;
  end;
end;
我只存储客户端IP并将其用作ID

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
  with TClient(AContext) do
  begin
    if AContext.Connection.Connected then
    begin
      PeerIP := Connection.Socket.Binding.PeerIP;
    end;
  end;
end;
可能像
ClientID:=Connection.Socket.Binding.Handle

procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
begin
 //Connection.Socket.Binding.Handle; ?? 
end;

PeerIP本身不够唯一,无法识别客户端。想想当路由器一侧运行的多个客户端连接到路由器另一侧运行的同一台服务器时会发生什么。从服务器的角度来看,客户端将具有相同的PeerIP(路由器的IP)。您需要将每个客户的PeerPort和PeerPort放在一起

  TClient = class(TIdServerContext)
  public
    PeerIP      : String;
    PeerPort    : TIdPort;
    procedure SendMessage(cIP: string; cPort: TIdPort; mStr : String);
  end;

procedure TClient.SendMessage(cIP: string; cPort: TIdPort; mStr : String);
var
  Context: TClient;
  List: TList;
  I: Integer;
begin
  List := Form1.IdTCPServer1.Contexts.LockList;
  try
    for I := 0 to List.Count-1 do
    begin
      Context := TClient(List[I]);
      if (Context <> Self) and (Context.PeerIP = cIP) and (Context.PeerPort = cPort) then
      begin
        Context.Connection.IOHandler.WriteLn(mStr);
        Break;
      end
    end;
  finally
    Form1.IdTCPServer1.Contexts.UnlockList;
  end;
end;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
  with TClient(AContext) do
  begin
    PeerIP := Connection.Socket.Binding.PeerIP;
    PeerPort := Connection.Socket.Binding.PeerPort;
  end;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
 ...
end;
TClient=class(TIdServerContext)
公众的
PeerIP:字符串;
对等端口:TIdPort;
过程发送消息(cIP:字符串;cPort:TIdPort;mStr:字符串);
结束;
过程TClient.SendMessage(cIP:string;cPort:TIdPort;mStr:string);
变量
上下文:TClient;
名单:TList ;;
I:整数;
开始
列表:=Form1.IdTCPServer1.Contexts.LockList;
尝试
对于I:=0到List.Count-1 do
开始
上下文:=TClient(列表[I]);
如果(Context Self)和(Context.PeerIP=cIP)和(Context.PeerPort=cPort),则
开始
Context.Connection.IOHandler.WriteLn(mStr);
打破
结束
结束;
最后
Form1.IdTCPServer1.Contexts.UnlockList;
结束;
结束;
过程TForm1.IdTCPServer1Connect(AContext:TIdContext);
开始
使用TClient(AContext)do
开始
PeerIP:=Connection.Socket.Binding.PeerIP;
PeerPort:=Connection.Socket.Binding.PeerPort;
结束;
结束;
过程TForm1.IdTCPServer1Execute(AContext:TIdContext);
开始
...
结束;
或者根本不依赖IP/端口。创建自己的唯一ID,例如要求每个客户端使用用户ID登录到服务器

  TClient = class(TIdServerContext)
  public
    UserID      : String;
    procedure SendMessage(cUser, mStr : String);
  end;

procedure TClient.SendMessage(cUser, mStr : String);
var
  Context: TClient;
  List: TList;
  I: Integer;
begin
  List := Form1.IdTCPServer1.Contexts.LockList;
  try
    for I := 0 to List.Count-1 do
    begin
      Context := TClient(List[I]);
      if (Context <> Self) and (Context.UserID = cUser) then
      begin
        Context.Connection.IOHandler.WriteLn(mStr);
        Break;
      end
    end;
  finally
    Form1.IdTCPServer1.Contexts.UnlockList;
  end;
end;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
  with TClient(AContext) do
  begin
    // this is just for demonstration. Obviously, you
    // should implement a real protocol with authentication,
    // duplicate login detection, etc...
    UserID := Connection.IOHandler.ReadLn;
  end;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
 ...
end;
TClient=class(TIdServerContext)
公众的
UserID:String;
过程发送消息(cUser,mStr:String);
结束;
过程TClient.SendMessage(cUser,mStr:String);
变量
上下文:TClient;
名单:TList ;;
I:整数;
开始
列表:=Form1.IdTCPServer1.Contexts.LockList;
尝试
对于I:=0到List.Count-1 do
开始
上下文:=TClient(列表[I]);
如果(Context Self)和(Context.UserID=cUser),则
开始
Context.Connection.IOHandler.WriteLn(mStr);
打破
结束
结束;
最后
Form1.IdTCPServer1.Contexts.UnlockList;
结束;
结束;
过程TForm1.IdTCPServer1Connect(AContext:TIdContext);
开始
使用TClient(AContext)do
开始
//这只是为了示范。显然,你
//应该实现具有身份验证的真实协议,
//重复登录检测等。。。
UserID:=Connection.IOHandler.ReadLn;
结束;
结束;
过程TForm1.IdTCPServer1Execute(AContext:TIdContext);
开始
...
结束;