gpt4 book ai didi

delphi - IdTCPServer 如何使用 OnExecute 发送和接收来自特定客户端的应答

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

几周前我开始使用 Indy TCPServer 和 TCPClient,现在,经过大量研究和 SOF 专家(特别是 Lebeau 先生)的帮助,我可以安全地管理客户端连接并向特定客户端发送字符串消息。这是一段代码:

type
TClient = class(TObject)
private
FHost: string;
public
FQMsg: TIdThreadSafeStringList; // Message Queue
constructor Create(const Host: string);
destructor Destroy; override;
end;

procedure TfrmMain.TCPServerExecute(AContext: TIdContext);
var
Client: TClient;
LQueue: TStringList;
WQueue: TStringList;
begin
with AContext.Connection.IOHandler Do
begin
DefStringEncoding := TEncoding.UTF8;
LQueue := nil;
Client := TClient(AContext.Data);
try
WQueue := Client.FQMsg.Lock;
try
if (WQueue.Count > 0) then
begin
LQueue := TStringList.Create;
LQueue.Assign(WQueue);
WQueue.Clear;
end;
finally
Client.FQMsg.Unlock;
end;
if (LQueue <> nil) then
Write(LQueue);
finally
LQueue.Free;
end;
end;
end;

现在是时候更进一步了,尝试从客户那里收到答复。但突然我意识到我不能使用 TCPServer 的 OnExecute 事件来“同时”发送消息和接收答案??我可能错了,但这段代码不起作用,我不知道为什么......

procedure TfrmMain.TCPServerExecute(AContext: TIdContext);
var
RStr: string;
Client: TClient;
LQueue: TStringList;
WQueue: TStringList;
begin
with AContext.Connection.IOHandler Do
begin
DefStringEncoding := TEncoding.UTF8;
// Send Cmd
LQueue := nil;
Client := TClient(AContext.Data);
try
WQueue := Client.FQMsg.Lock;
try
if (WQueue.Count > 0) then
begin
LQueue := TStringList.Create;
LQueue.Assign(WQueue);
WQueue.Clear;
end;
finally
Client.FQMsg.Unlock;
end;
if (LQueue <> nil) then
Write(LQueue);
finally
LQueue.Free;
end;
// Receive Data
RStr := Trim(ReadLn);
if (RStr <> '') then
begin
SyncLog(RStr);
end;
end;
end;

当我将最后一部分 (ReadLn) 添加到一起时,代码的第一部分不起作用,我无法再向客户端发送消息:(

拜托,有人知道我错过了什么吗?

谢谢!

最佳答案

首先,使用 TIdTextEncoding.UTF8 而不是 TEncoding.UTF8(如果升级到 Indy 10.6+,则使用 IndyTextEncoding_UTF8),然后移动DefStringEncoding 分配给 OnConnect 事件。您只需分配一次,而不是在每次读/写时分配。

其次,ReadLn()是一个阻塞方法。它会退出,直到实际读取一行,或者发生超时/错误。因此,要执行您正在尝试的操作,您必须在实际读取入站数据之前检查是否存在入站数据,以便您可以超时并退出并让 OnExecute 循环返回以再次检查队列。

尝试这样的事情:

type
TClient = class(TObject)
private
FHost: string;
FQMsg: TIdThreadSafeStringList; // Message Queue
public
constructor Create(const Host: string);
destructor Destroy; override;
property QMsg: TIdThreadSafeStringList read FQMsg;
end;

procedure TfrmMain.TCPServerConnect(AContext: TIdContext);
var
Client: TClient;
begin
AContext.Connection.IOHandler.DefStringEncoding := TIdTextEncoding.UTF8;
...
Client := TClient.Create;
...
AContext.Data := Client;
...
end;

procedure TfrmMain.TCPServerExecute(AContext: TIdContext);
var
RStr: string;
Client: TClient;
LQueue: TStringList;
WQueue: TStringList;
begin
Client := TClient(AContext.Data);
// Send Cmd
LQueue := nil;
try
WQueue := Client.QMsg.Lock;
try
if (WQueue.Count > 0) then
begin
LQueue := TStringList.Create;
LQueue.Assign(WQueue);
WQueue.Clear;
end;
finally
Client.QMsg.Unlock;
end;
if (LQueue <> nil) then
AContext.Connection.IOHandler.Write(LQueue);
finally
LQueue.Free;
end;
// Receive Data
if AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
if not AContext.Connection.IOHandler.CheckForDataOnSource(100) then Exit;
AContext.Connection.IOHandler.CheckForDisconnect;
end;
RStr := Trim(AContext.Connection.IOHandler.ReadLn);
if (RStr <> '') then
begin
SyncLog(RStr);
end;
end;

关于delphi - IdTCPServer 如何使用 OnExecute 发送和接收来自特定客户端的应答,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27612095/

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