Delphi:如何将文本发送到连接到服务器套接字的特定客户端,知道他们的本地IP地址?

时间:2016-08-08 17:26:11

标签: sockets delphi delphi-2010

我正在通过网络为我的IT班工作一个基于文本的小型消息传递平台。

一切正常,但现在我尝试实现一个私人消息功能,您实际上输入了朋友的IP和消息,并将其发送到服务器并且能够发送消息与该IP相关的特定客户。

我有一切正常,除了我无法弄清楚如何根据IP地址向一个特定客户发送文本。我认为如果temp2是字符串并且msgIP是目标IP并且msg是消息,我将能够这样做:

for I := 1 to ServerSocket1.Socket.ActiveConnections do
begin
  temp2:=ServerSocket1.Socket.Connections[i];
  if temp2=msgIP then
  begin
    ServerSocket1.Socket.Connections[i].SendText(msg);
  end;
end;

1 个答案:

答案 0 :(得分:5)

您的代码中有三个错误:

  1. Connections[]属性使用从0开始的索引,但您的循环使用的是基于1的索引。您将始终跳过第一个连接,并在尝试访问最后一个连接时崩溃。

  2. Connections[]属性返回TCustomWinSocket对象指针,而不是字符串。您需要将目标IP字符串与对象的RemoteAddress属性值进行比较。

  3. 如果找到匹配项,您不会破坏循环。

  4. 请改为尝试:

    var
      client: TCustomWinSocket;
    begin
      for I := 0 to ServerSocket1.Socket.ActiveConnections-1 do
      begin
        client := ServerSocket1.Socket.Connections[i];
        if client.RemoteAddress = msgIP then
        begin
          client.SendText(msg);
          break;
        end;
      end;
    end;
    

    现在,据说,从服务器的角度来看,知道RemoteAddress是远程客户端的IP。如果客户端通过代理或NAT /路由器连接到服务器,则RemoteAddress IP将是代理/ NAT的IP,而不是客户端本身。可以通过相同的代理/ NAT连接多个客户端,因此它们都具有相同的RemoteAddress IP。如果这仅适用于课程作业且不涉及代理/ NAT,那么RemoteAddress可能没问题,只要您不在同一台计算机上同时运行多个应用实例。

    要唯一标识服务器上的特定客户端,无论其如何连接到服务器,您都需要使用客户端RemoteAddress {{1} }属性值在一起:

    RemotePort

    然而,当一个客户希望与另一个客户通信时,使用IP +端口并不是非常直观,特别是如果他们不了解彼此的端口值。

    更好的选择是让每个客户端使用唯一标识符(例如用户名)登录服务器。您可以使用客户端的var client: TCustomWinSocket; begin for I := 0 to ServerSocket1.Socket.ActiveConnections-1 do begin client := ServerSocket1.Socket.Connections[i]; if (client.RemoteAddress = msgIP) and (client.RemotePort = msgPort) then begin client.SendText(msg); break; end; end; end; 属性来跟踪每个客户端数据并根据需要进行比较,例如:

    TCustomWinSocket.Data

    这样,您可以将消息发送到特定客户端,无论其位于何处以及如何连接到服务器。特别是如果客户端断开连接并重新连接,其IP /端口每个连接都会更改。登录标识符将更加一致且更易于使用。