2015-03-03 185 views
3

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

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; 

回答

6

单独的PeerIP是不够的唯一识别客户端。想想在路由器一侧运行的多个客户端连接到路由器另一侧运行的同一台服务器时会发生什么。从服务器的角度来看,客户端将具有相同的PeerIP(路由器的IP)。您需要将每个客户端的PeerIP和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; 

或根本不依赖于IP /端口。制作您自己的唯一ID,例如要求每个客户端用UserID登录到服务器。

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; 
相关问题