gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 02:42:43 27 4
gpt4 key购买 nike

我正在创建一个仅在 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com