Einzelnen Beitrag anzeigen

romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.164 Beiträge
 
Delphi 10 Seattle Professional
 
#1

IdTCPServer/IdTCPClient: Vom Server richtig trennen???

  Alt 7. Dez 2006, 12:54
Hallo!

Ich schreibe ein kleines Client/Server Programm und benutze dafür die TIdTCPServer und TIdTCPClient von Indy. Der Server hat eine Liste (in meinem Fall eine TStringList), in die ab und zu neue Strings hinzufügt werden. Jeder neuer String soll sofort an alle verbundenen Clients gesendet werden. Und es funktioniert auch. Zum Problem kommt es, wenn ein Client die Verbindung zum Server trennen möchte. Der Server hällt die Verbindung so länge fest, bis er etwas an den Client sendet. Erst dann merkt der Server, dass die Verbindung nicht mehr existiert. Warum ist es so und was kann man dagegen tun?

Hier mein Programm:

Server:


Delphi-Quellcode:
...
type
  TfrmMain = class(TForm)
    Server: TIdTCPServer;
    procedure ServerConnect(AThread: TIdPeerThread);
    procedure ServerDisconnect(AThread: TIdPeerThread);
    procedure ServerExecute(AThread: TIdPeerThread);
  private
    { Private declarations }
  public
    { Public declarations }
end;

type
  TClientClass = class
  private
    PeerThread: TIdPeerThread;
end;

var
  frmMain: TfrmMain;
  ListData: TStringList;
  ClientList: TList;

...
...
...

procedure TfrmMain.ServerConnect(AThread: TIdPeerThread);
begin
  AThread.Data:= TClientClass.Create();
  ClientList.Add(AThread.Data);
  TClientClass(AThread.Data).PeerThread := AThread;
end;

procedure TfrmMain.ServerDisconnect(AThread: TIdPeerThread);
begin
  ClientList.Delete(ClientList.IndexOf(AThread.Data));
end;

procedure TfrmMain.ServerExecute(AThread: TIdPeerThread);
var
  i: integer;
  LastIndex: integer;
begin
  LastIndex := ListData.Count;
  while AThread.Connection.Connected do
  begin
     Sleep(1);
     if ListData.Count > LastIndex then
     begin
       LastIndex := ListData.Count;
       for i := ListData.Count - LastIndex downto 0 do
       AThread.Connection.WriteLn(ListData.Strings[i] + #13#10);
     end;
  end;
end;

...
Client:


Delphi-Quellcode:
...
type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    cbConnectDisconnect: TCheckBox;
    procedure cbConnectDisconnectClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TClientThread = class(TThread)
  constructor Create (CreateSuspended: Boolean);
  destructor Destroy; override;
  private
    TCPClient: TIdTCPClient;
  protected
    procedure Execute; override;
end;

var
  Form1: TForm1;
  ClientThread: TClientThread;

implementation

{$R *.dfm}

constructor TClientThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := true;
end;

destructor TClientThread.Destroy;
begin
  ClientThread := nil;
  if Form1.cbConnectDisconnect.Checked then
  begin
    if not Assigned(ClientThread) then
    ClientThread := TClientThread.Create(false);
  end;
end;


procedure TClientThread.Execute;
begin
  TCPClient := TIdTCPClient.Create(nil);
  TCPClient.Host := 'localhost';
  TCPClient.Port := 44497;
  try
    TCPClient.Connect;
    while not Terminated and TCPClient.Connected do
    begin
       Form1.ListBox1.Items.Insert(0, TCPClient.ReadLn);
    end;
    if TCPClient.Connected then
    TCPClient.Disconnect;
    TCPClient.Free;
  except
  end;
end;

procedure TForm1.cbConnectDisconnectClick(Sender: TObject);
begin
  if CheckBox1.Checked = true then
  begin
     if not Assigned(ClientThread) then
     ClientThread := TClientThread.Create(false);
  end
  else
  begin
     if Assigned(ClientThread) then
     begin
        ClientThread.Terminate;
     end;
  end;
end;

...
...
  Mit Zitat antworten Zitat