线程:将数据发送到特定的活动线程

时间:2015-06-12 15:39:01

标签: multithreading indy lazarus

我有一个相当好奇的问题。我有一个使用Lazarus 1.4和Indy 10构建的多线程客户端服务器应用程序,我正在努力。它使用线程发送&从服务器接收数据流。为此,每个模块都创建自己的自终止工作线程。但是,我还需要创建一个特殊的消息工作线程,它接收来自服务器的消息,就像数据库备份正在进行时一样。此消息线程由应用程序mainform&创建。只要客户端应用程序处于活动状态,它就会保持活动状态。

服务器处理数据的发送 - 消息或数据库数据 - 没有问题。问题是如何确保在客户端,服务器消息只能由消息线程读取。所有线程都有Execute()过程来处理服务器通信。

我的问题

  1. 使用消息线程的线程ID可以让我在服务器传递消息时直接定位消息线程。

  2. 或者,将消息限制为特定大小有助于过滤针对客户端消息线程的消息(这是我实际使用的,但有时会失败)。

  3. 我可以补充说,所有客户端线程都使用通用的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内容,其大小等于或大于消息协议但严格小于数据协议。这就是我计划筛选服务器发送的流的方式。

0 个答案:

没有答案