Delphi - Indy TCPServer 如何管理客户端连接?

标签 delphi tcp indy

我正在创建一个仅在 Windows 操作系统上运行的客户端-服务器应用程序,每个 Windows 用户将一次连接到服务器。局域网使用DHCP,所以IP不固定。

我需要将字符串消息从 IdTCPServer 发送到特定的 IdTCPClient。一开始我使用的是列表框,所以我在连接时将主机名添加到列表框,在断开连接时将其删除。当时,Remy Lebeau 给了我这个提示:

procedure TfrmMain.sendButtonClick(Sender: TObject);
var
  Index: Integer;
  Ctx: TIdContext;
begin
  Index := ListBox.ItemIndex;
  if Index = -1 then Exit;
  Context := TIdContext(ListBox.Items.Objects[Index]);
  // use Context as needed...
end;

但现在我使用的是带有预添加主机名的 ListView。所以我只是在客户端连接或断开连接时更改列表框项目图像状态。现在我正在尝试这样的事情:

procedure TfrmMain.TCPServerConnect(AContext: TIdContext);
begin
  TThread.Queue(nil,
    procedure
    var
      Host: String;
      LItem: TListItem;
    begin
      Host := UpperCase(GStack.HostByAddress(Ctxt.Binding.PeerIP));
      LItem := lvwPCList.FindCaption(0, Host, False, True, False);
      if (LItem <> nil) then LItem.Data := AContext.Data;
    end
  );
end;

一旦我将 Listview Item 与 Context 数据链接起来,我就会尝试将消息直接发送给客户端:

procedure TfrmMain.SendMessage(const Item: TListItem; const Msg: String);
var
  Ctx: TIdContext;
begin
  if (Trim(Msg) = '') then Exit;
  Ctx := TIdContext(Item.Data);
  try
    Ctx.Connection.IOHandler.WriteLn(Msg);
  except
  end;
end;

我可以编译这段代码,但消息永远不会到达客户端。请问,我做错了什么?

谢谢!

最佳答案

您应该在您的 TIdContext 继承中实现一个唯一的 session ID。在每个新连接上生成一个新的唯一 ID。例如,您可以使用递增的整数,或生成 GUID。在任何情况下,您都有自己唯一的“ session ID”,它唯一标识客户端/服务器“ session ”。这是假设您希望完成某种 session 管理。

至于循环,还是需要循环查找对应的client。但是这样的循环是微不足道的,并且可以在几分之一毫秒内执行,即使有数千个连接的客户端(这已经在任何服务器上进行了大修)。即使您要依赖内置的东西,该内置函数本质上仍然会执行循环。

您不能简单地通过主机名或 IP 地址来引用连接的客户端,因为可能有来自同一客户端的多个连接。由于这个事实,没有“通过主机或 IP 向客户端发送消息”这样的事情。您需要明确引用特定的连接。不要担心你的连接是否来自同一台计算机/设备,除非你打算严格禁止来自同一台设备的多个连接但即便如此,如果你决定通过互联网使用它,所有背后的客户端相同的网络将被视为相同的 IP。这同样适用于其他设备的想法,而不仅仅是 Windows。将来,您可能希望支持其他设备,并且如果您计划某天走那条路,则需要确保您的结构已为此做好准备。

关于Delphi - Indy TCPServer 如何管理客户端连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27461013/

相关文章:

Delphi运算符^,什么意思?

delphi - 从主线程更改线程的变量值是否安全?

python - 将 Python 代码转换为 Delphi 代码

delphi - Delphi XE6 中 datasnap 服务器方法调用后文件删除

Delphi:大文件(100 MB)快速流式传输到 sha256

c++ - 在 Node.js 中使用 native 代码的最佳方式是什么?

c - 来自套接字的 "reading zero bytes"是监视 POSIX C 中 TCP/IP 断开连接的有效方法吗?

ruby - 为什么 ruby​​ 无法在我的 Fedora 20 机器上打开 TCPSocket?

delphi - Indy 10 FTP 空列表

delphi - 如何使用 datasnap 获取作为 header 传递的 token ?