2015-03-03 4 views
3

Каков правильный способ идентификации клиентов, если у них одинаковые IP-адреса и порты? Если они подключены только через LAN, например. ip: 198.162.1.1 port: 2015. Как определить, какой клиент отключился, используя свой уникальный идентификатор, если он имеет один и тот же IP-адрес?Как отличить соединения от нескольких клиентов с тем же 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-адрес клиента и использую его как идентификатор.

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/Port вообще. Создайте свой собственный уникальный идентификатор, например, чтобы каждый клиент заходил на сервер с помощью 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; 

 Смежные вопросы

  • Нет связанных вопросов^_^