ververicka
ververicka

Reputation: 175

TCP IP server client delphi when running client abstract error

Hi I am trying to build tcp server client application in Delphi I have this code

unit UnitClientServer;

interface

uses
  IdCustomTCPServer, IdTCPClient, IdContext,
  SysUtils, Classes, Forms, StdCtrls, Controls, System.Actions, Vcl.ActnList;

type
  TMyPushClientThread = class(TThread)
  private
    TCPClient: TIdTCPClient;
    FLog: TStrings;
  public
    constructor Create(AHost: string; APort: Word; ALog: TStrings);
    destructor Destroy; override;
    procedure Execute; override;
  end;

  TMyPushServer = class (TIdCustomTCPServer)
  protected
    function DoExecute(AContext: TIdContext): Boolean; override;
  end;

  TServerPushExampleForm = class(TForm)
    MemoLog: TMemo;

    aclMain: TActionList;
    Button1: TButton;
    actStartClient: TAction;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure actStartClientExecute(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    ExampleClient: TMyPushClientThread;
    ExampleServer: TMyPushServer;
  end;

var
  ServerPushExampleForm: TServerPushExampleForm;

implementation

uses
  IdGlobal;

{$R *.dfm}

procedure TServerPushExampleForm.actStartClientExecute(Sender: TObject);
//var MyClient : TMyPushClientThread;
var myTstring : TStrings;

begin
     FreeAndNil(ExampleClient);
     myTstring := TStrings.Create;
     myTstring.Add('My log');


     ExampleClient:= TMyPushClientThread.Create('localhost', 8088, myTstring)  ;
   //  MyClient.Execute;
end;

procedure TServerPushExampleForm.Button2Click(Sender: TObject);
var myTstring : TStrings;
begin
      FreeAndNil(ExampleClient);
     myTstring := TStrings.Create;
     myTstring.Add('My log stevilka 1');
     ExampleClient := TMyPushClientThread.Create('localhost', 8088,myTstring );
end;

procedure TServerPushExampleForm.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
     // MainWindow.actServer.Enabled := True;
end;

procedure TServerPushExampleForm.FormCreate(Sender: TObject);
begin
  ExampleServer := TMyPushServer.Create;
  ExampleServer.DefaultPort := 8088;
  ExampleServer.Active := True;

  ExampleClient := TMyPushClientThread.Create('localhost', 8088, MemoLog.Lines);
end;

procedure TServerPushExampleForm.FormDestroy(Sender: TObject);
begin
  ExampleServer.Free;
  ExampleClient.Terminate;
  ExampleClient.WaitFor;
  ExampleClient.Free;
end;

{ TMyPushServer }

function TMyPushServer.DoExecute(AContext: TIdContext): Boolean;
begin
  Result := inherited;

  // simulate hard work
  Sleep(Random(3000));

  AContext.Connection.IOHandler.WriteLn(
    'Completed at ' + TimeToStr(Now), TIdTextEncoding.UTF8 );
end;

{ TMyPushClientThread }

constructor TMyPushClientThread.Create(AHost: string; APort: Word; ALog: TStrings);
begin
  inherited Create(False);

  FLog := ALog;

  TCPClient := TIdTCPClient.Create;
  TCPClient.Host := AHost;
  TCPClient.Port := APort;
  TCPClient.ReadTimeout := 500;
end;

destructor TMyPushClientThread.Destroy;
begin
  TCPClient.Free;
  inherited;
end;

procedure TMyPushClientThread.Execute;
var
  S: string;
begin
  TCPClient.Connect;

  while not Terminated do
  begin
    S := TCPClient.IOHandler.ReadLn(TIdTextEncoding.UTF8 );

    if not TCPClient.IOHandler.ReadLnTimedout then
    begin
      TThread.Queue(nil,
        procedure
        begin
          FLog.Append(S);
        end);
    end;

  end;

  TCPClient.Disconnect;
end;

end.

When I call this button function :

 procedure TServerPushExampleForm.actStartClientExecute(Sender: TObject);
//var MyClient : TMyPushClientThread;
var myTstring : TStrings;

begin
     FreeAndNil(ExampleClient);
     myTstring := TStrings.Create;
     myTstring.Add('My log');


     ExampleClient:= TMyPushClientThread.Create('localhost', 8088, myTstring)  ;
   //  MyClient.Execute;
end;

I get error Abstract error. why I can't run the client what is the problem? I found this code in this post How to continuously send messages with TIdTCPServer?

Upvotes: 0

Views: 330

Answers (1)

Ondrej Kelle
Ondrej Kelle

Reputation: 37221

TStrings is an abstract class. Using abstract classes produces compiler warnings and runtime errors. You need to use a concrete descendant instead, such as TStringList, e.g.:

myTstring := TStringList.Create;

Upvotes: 4

Related Questions