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;
...
...