Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
IdTCPServer Freeze on Delphi
#4
(04-19-2020, 11:48 AM)3ddark Wrote: I edited and tested the code with your suggestion. The result is the same for Delphi.

The VCL code looks fine. There should be no freezing.

(04-19-2020, 11:48 AM)3ddark Wrote: I test on Ubuntu(18.04) Console app. I got the same result on Linux

Your Linux code is not servicing the TThread.Queue() requests, so they never execute your handlers. Since you are not using a UI message loop, you need a manual loop that calls the RTL's CheckSynchronize() function periodically.

It is also important NOT to access the members of TIdContext asynchronously, especially after a disconnect, since the TIdContext object will be destroyed after the OnDisconnect handler exits, and will likely not exist anymore before (or worse, while) your TThread.Queue() handler is run. That is why in the code I provided you, I use the TIdContext pointer only as a lookup key in the TListBox, nothing more. In your Linux code, you don't need the TIdContext pointer at all.

Try this:

Code:
//Delphi Console App for Linux
program Project3;

{$APPTYPE CONSOLE}

{$R *.res}

uses
    System.SysUtils
  , System.Classes
  , System.Threading
  , IdContext
  , IdBaseComponent
  , IdComponent
  , IdCustomTCPServer
  , IdTCPServer;

type
  TSocketServer = class
  private
    procedure HandleClientConnected(APeerIP: string; APeerPort: Integer);
    procedure HandleClientDisconnected();
    procedure UpdateClientsCount;
  public
    IdTCPServer1: TIdTCPServer;

    procedure IdTCPServer1Connect(AContext: TIdContext);
    procedure IdTCPServer1Disconnect(AContext: TIdContext);
    procedure IdTCPServer1Execute(AContext: TIdContext);
    constructor Create();
    destructor Destroy; override;
  end;

var
  Server: TSocketServer;

constructor TSocketServer.Create();
begin
  inherited;
  IdTCPServer1 := TIdTCPServer.Create;
  IdTCPServer1.DefaultPort := 20000;

  IdTCPServer1.OnConnect := IdTCPServer1Connect;
  IdTCPServer1.OnDisconnect := IdTCPServer1Disconnect;
  IdTCPServer1.OnExecute := IdTCPServer1Execute;

  IdTCPServer1.Active := True;
end;

destructor TSocketServer.Destroy;
begin
  IdTCPServer1.Active := False;
  inherited;
end;

procedure TSocketServer.HandleClientConnected(APeerIP: string; APeerPort: Integer);
begin
  Writeln(APeerIP + ':' + APeerPort.ToString);
  UpdateClientsCount;
end;

procedure TSocketServer.HandleClientDisconnected();
begin
  UpdateClientsCount;
end;

procedure TSocketServer.IdTCPServer1Connect(AContext: TIdContext);
var
  PeerIP: string;
  PeerPort: Integer;
begin
  PeerIP := AContext.Binding.PeerIP;
  PeerPort := AContext.Binding.PeerPort;

  TThread.Queue(nil,
    procedure
    begin
      HandleClientConnected(PeerIP, PeerPort);
    end
  );
end;

procedure TSocketServer.IdTCPServer1Disconnect(AContext: TIdContext);
begin
  TThread.Queue(nil,
    procedure
    begin
      HandleClientDisconnected();
    end
  );
end;

procedure TSocketServer.IdTCPServer1Execute(AContext: TIdContext);
var
  data: string;
begin
  data := AContext.Connection.IOHandler.ReadLn;
  if data = 'E' then
    AContext.Connection.Disconnect;
end;

procedure TSocketServer.UpdateClientsCount;
var
  List : TIdContextList;
  Count: Integer;
begin
  if IdTCPServer1.Active then
  begin
    List := IdTCPServer1.Contexts.LockList;
    try
      Count := List.Count;
    finally
      IdTCPServer1.Contexts.UnlockList;
    end;
  end else begin
    Count := 0;
  end;
  Writeln('Server - Client : ' + Count.ToString);
end;

begin
  Server := TSocketServer.Create;
  try
    while True do
    begin
      try
        CheckSynchronize(100);
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end;
  finally
    Server.Free;
  end;
end.

Reply


Messages In This Thread
IdTCPServer Freeze on Delphi - by 3ddark - 04-18-2020, 08:30 PM
RE: IdTCPServer Freeze on Delphi - by rlebeau - 04-18-2020, 09:37 PM
RE: IdTCPServer Freeze on Delphi - by 3ddark - 04-19-2020, 11:48 AM
RE: IdTCPServer Freeze on Delphi - by rlebeau - 04-20-2020, 07:11 PM
RE: IdTCPServer Freeze on Delphi - by TangoEcho - 01-28-2022, 02:24 PM
RE: IdTCPServer Freeze on Delphi - by 3ddark - 04-21-2020, 08:39 AM
RE: IdTCPServer Freeze on Delphi - by rlebeau - 04-21-2020, 06:05 PM
RE: IdTCPServer Freeze on Delphi - by 3ddark - 04-22-2020, 05:59 AM
RE: IdTCPServer Freeze on Delphi - by 3ddark - 04-23-2020, 01:57 PM
RE: IdTCPServer Freeze on Delphi - by rlebeau - 04-23-2020, 04:48 PM

Forum Jump:


Users browsing this thread: 2 Guest(s)