IdTcpClient仅接收一次Windows服务

时间:2019-07-20 01:12:13

标签: delphi indy

我不知道为什么,但是我的Windows服务应用程序一次仅从TcpServer接收信息(在Windows服务启动时),线程仍在运行,但始终停留在Service1.Cliente.IOHandler.ReadBytes(FData,szProtocol,False );

已经在正常的Windows应用程序上进行了测试,并且工作正常,但是移动到Windows服务时只能接收一次并停止。 PS:线程仍在运行。

    constructor TReadingThread.Create(AClient: TIdTCPClient);
begin
  inherited Create(True);
  FClient := AClient;
end;

procedure TReadingThread.Execute;
begin
  FreeOnTerminate := False;

  while not Terminated do
  begin
    if Service1.Cliente.Connected then
    begin
      if not Service1.Cliente.IOHandler.InputBufferIsEmpty then
      begin
        Service1.Cliente.IOHandler.ReadBytes(FData, szProtocol, False);
        if (FData <> nil) and Assigned(FOnData) then Synchronize(DataReceived);
        CriaLog('Received something');
      end;
    end;

    Sleep(1);
  end;
end;

procedure TReadingThread.DataReceived;
begin
  if Assigned(FOnData) then FOnData(FData);
end;

在普通应用程序中,相同的代码可以正常工作,但是当该应用程序是Windows服务时,会发生此问题。

雷米的答案,这是szProtocol的定义方式以及更多用途:

type
  TCommand = (
    cmdConnect,
    cmdDisconnect,
    cmdLibera);

type
  TClient = record
    HWID    : String[40];
    Msg     : String[200];
 end;

const
  szClient = SizeOf(TClient);

type
  TProtocol = record
    Command: TCommand;
    Sender: TClient;
    DataSize: Integer;
end;

const
  szProtocol = SizeOf(TProtocol);

我用来接收信息的TThread结构定义为:

type
  TDataEvent = procedure(const LBuffer: TIdBytes) of object;

  TReadingThread = class(TThread)
  private
    FClient : TIdTCPClient;
    FData   : TIdBytes;
    FOnData : TDataEvent;
    procedure DataReceived;
  protected
    procedure Execute; override;
  public
    constructor Create(AClient: TIdTCPClient); reintroduce;
    property OnData: TDataEvent read FOnData write FOnData;
  end;

此过程是谁向我显示从服务器收到的内容,我会执行一些操作。

procedure TService1.DataReceived(const LBuffer: TIdBytes);
type
  PTBytes   = ^TBytes;
  PTIdBytes = ^TIdBytes;
var
  LDataSize   : Integer;
  LProtocol   : TProtocol;
begin
  LProtocol := BytesToProtocol(PTBytes(@LBuffer)^);

  case LProtocol.Command of
    cmdLibera:
    begin
    // action
    end;
  end;
end;

以及TTHread结构中的其他功能:

constructor TReadingThread.Create(AClient: TIdTCPClient);
begin
  inherited Create(True);
  FClient := AClient;
end;

procedure TReadingThread.DataReceived;
begin
  if Assigned(FOnData) then FOnData(FData);
end;

我知道代码有效,因为正如我所说,我在正常的应用程序(不是服务)上使用了它,并且一切正常,但是在服务下它不起作用。

1 个答案:

答案 0 :(得分:0)

答案是,只需添加一个“打包”即可解决问题,谢谢雷米。