我有一个相当好奇的问题。我有一个使用Lazarus 1.4和Indy 10构建的多线程客户端服务器应用程序,我正在努力。它使用线程发送&从服务器接收数据流。为此,每个模块都创建自己的自终止工作线程。但是,我还需要创建一个特殊的消息工作线程,它接收来自服务器的消息,就像数据库备份正在进行时一样。此消息线程由应用程序mainform&创建。只要客户端应用程序处于活动状态,它就会保持活动状态。
服务器处理数据的发送 - 消息或数据库数据 - 没有问题。问题是如何确保在客户端,服务器消息只能由消息线程读取。所有线程都有Execute()过程来处理服务器通信。
我的问题
使用消息线程的线程ID可以让我在服务器传递消息时直接定位消息线程。
或者,将消息限制为特定大小有助于过滤针对客户端消息线程的消息(这是我实际使用的,但有时会失败)。
我可以补充说,所有客户端线程都使用通用的IdTCPClient来读取服务器通信。我使用关键部分来保护它。
消息线程的代码如下所示:
procedure TMsgThread.Execute;
var
LBuffer: TBytes;
LMessage: TBytes;
LDataSize: Integer;
LMsgProtocol: TMsgProtocol;
begin
//inherited; // Gives abstract methods cannot be called directly
// while the thread is not terminated and the client is connected
while NOT Terminated and FTCPClient.Connected do
begin
Lock;
//
try
if not FTCPClient.IOHandler.InputBufferIsEmpty and
(FTCPClient.IOHandler.InputBuffer.Size >= szMsgProtocol) and
(FTCPClient.IOHandler.InputBuffer.Size < szProtocol) then
begin
InitMsgProtocol(LMsgProtocol);
// store the size of the InputBuffer in LDataSize
LDataSize := FTCPClient.IOHandler.InputBuffer.Size;
if LDataSize >= szMsgProtocol then
try
// then read from InputBuffer the size of the protocol structure
FTCPClient.IOHandler.ReadBytes(LBuffer, szMsgProtocol);
// convert array of bytes to protocol
LMsgProtocol := BytesToMsgProtocol(LBuffer);
// check the command
case LMsgProtocol.Command of
cmdBackupDatabase:
begin
//
end; // cmdBackup: begin
cmdPulse:
begin
// Read the message sent by the server
FMessage := LMsgProtocol.Message;
// set the command to cmdKeepAlive
LMsgProtocol.Command := cmdKeepAlive;
// Convertir le protocol en bytes
LBuffer := MsgProtocolToBytes(LMsgProtocol);
// Envoyez la requête en bytes au serveur
FTCPClient.IOHandler.Write(LBuffer);
//
Synchronize(@Self.DoConnectionAlive);
end;
end; // case LProtocol.Command of
finally
// clear buffer and message
ClearBuffer(LBuffer);
ClearBuffer(LMessage);
end; // tryf
Sleep(100);
end;
finally
Unlock;
end;
end; // while NOT Terminated and FTCPClient.Connected do begin
end;
其他自终止线程的Execute方法在结构上与上面显示的类似。我是从互联网上的模型中得到的。 szMsgProtocol是消息协议的大小,而szProtocol是数据协议的大小。 基本上,在上面的Execute()中,我关注的是InputBuffer内容,其大小等于或大于消息协议但严格小于数据协议。这就是我计划筛选服务器发送的流的方式。