Autor Beitrag
Quitzlinga
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 60
Erhaltene Danke: 2

Win XP
Delphi 2007 Prof. Codegear Win32
BeitragVerfasst: Do 27.09.07 13:18 
Hallo zusammen

Ich habe mit der INDY10 Komponente von Delphi ein einfaches Chatprogramm geschrieben, mit dem Textnachrichten untereinander ausgetauscht werden können. Diese funktioniert beim Halten der Verbindung (also kein connect und disconnect zwischen den Sendungen) auch so, wie gewünscht. Nun wollte ich das Programm annähernd verbindungslos gestalten, also nur eine Verbindung aufbauen, wenn diese auch benötigt wird und sie danach sofort wieder zu kappen. Bei zu schnellem Aufbauen und Kappen der Verbindung gehen mir jedoch Daten verloren. Benutzen tue ich zwei TIdTCPServer-Komponenten zum empfangen und eine TIdTCPClient-Komponente zum senden, die jeweils auf den Empfänger eingestellt wird. Schreibe ich das Programm um, so das die Verbindung ständig gehalten wird, funktioniert es problemlos. Meine Frage ist, kennt jemand eine Methode, um das Programm in der Client-Sende Routine solange warten zu lassen, bis die vorherige Verbindung tatsächlich abgebrochen ist (Ein Repeat until RSPPClient.Disconnected = False) bringt leider nichts und ein Sleep erscheint mir doch zu sehr die Holzhammermethode.

Wenn jemand eine Lösung für das Problem hat, wäre ich Ihm sehr dankbar. Die vorherrschende Methode ist leider die mit dem Verbindung halten bzw. einfach davon auszugehen, das inzwischen genug Zeit zwischen dem Connect und Disconnect verstrichen ist.

MfG

Quitzlinga

Technik : 2 TIdTCPServer zum empfangen (beide auf verschiedenen Ports)
1 TIdClient zum senden

Zum besserem Beispiel etwas Code aus meinem Programm

Client

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TRSPPBase.CastTextMessage(IP : String;TheMessage : string);
var
  Msg  : String;

begin
  Msg := Trim(TheMessage);
  try
    RSPPSend.Host := IP;             // IP des Empfängers (kann Server 1 oder 2 sein)
                                     // Port wird am Anfang des Programms gesetzt
    RSPPSend.Connect;                // Verbinden
    RSPPSend.IOHandler.WriteLn(Msg); // Nachricht übermitteln
    RSPPSend.Disconnect;             // Und wieder trennen
  except
    on E : Exception do begin
      ShowMessage(E.Message);
    end;
  end;
end;


Server

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TRSPPBase.RSPPServerExecute(AContext: TIdContext);
var
  Msg,IP    : String;
  Client    : TSimpleClient;

begin
  // Client setzen
  Client := getClient(AContext.Binding.PeerIP);
  IP := Client.DNS;
  // Text vom Client holen
  Msg := AContext.Connection.IOHandler.ReadLn();
  ... Verarbeitung der Nachricht
end;


Hier treten die Fehler auf

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
procedure TRSPPBase.RSPPServerConnect(AContext: TIdContext);
var
  Client : TSimpleClient;
  IP : String;

begin
  // Testen ob bereits connected
  IP := AContext.Binding.PeerIP;
  if not IPFound(IP)
     then begin
       // Client erzeugen
       Client := TSimpleClient.Create;
       // und Werte zuweisen
       Client.DNS  := IP;
       Client.Name := 'Logging In';
       Client.ListLink := ClientLB.Items.Count;
       // und Client der Listbox hinzufügen
       ClientLB.Items.Add(Client.Name);
       // und der Clients-Liste hinzufuegen
       Clients.Add(Client);
       // Willkommensnachricht senden (Die folgenden Nachrichten
       // kommen nur unregelmässig an
       // Vermutlich weil die Verbindung noch nicht richtig abgebaut wurde
       CastTextMessage(IP,'/TEXT Verbindung hergestellt...');
       CastTextMessage(IP,'/TEXT Willkommen bei RSPP V1.0...');
       CastTextMessage(IP,'/TEXT Bitte Logindaten senden...');
       CastTextMessage(IP,'/LOGIN');
     end;
end;
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 27.09.07 16:49 
Moin und :welcome: im Forum!

user profile iconQuitzlinga hat folgendes geschrieben:
Diese funktioniert beim Halten der Verbindung (also kein connect und disconnect zwischen den Sendungen) auch so, wie gewünscht. Nun wollte ich das Programm annähernd verbindungslos gestalten, also nur eine Verbindung aufbauen, wenn diese auch benötigt wird und sie danach sofort wieder zu kappen. Bei zu schnellem Aufbauen und Kappen der Verbindung gehen mir jedoch Daten verloren. Benutzen tue ich zwei TIdTCPServer-Komponenten zum empfangen und eine TIdTCPClient-Komponente zum senden

Dafür ist TCP auch nicht wirklich gut geeignet. Warum machst du es nicht gleich per UDP, wenn es verbindungslos sein soll?! :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Quitzlinga Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 60
Erhaltene Danke: 2

Win XP
Delphi 2007 Prof. Codegear Win32
BeitragVerfasst: Do 27.09.07 19:09 
Hi Narses

Vielen Dank erstmal für die freundliche Begrüssung. :D

Das UDP-Protokoll ist für mich nicht so geeignet, da es komplett verbindungslos ist und die Datenpakete wirklich an jeden gesendet werden, selbst an die, die das nicht angeht. Da das Programm natürlich später nicht nur ein Chat sein soll (ist nur der erste Aufbau, um die Funktionalität mal zu prüfen und die Indykomponenten mal kennen zu lernen), sondern auch Dateien/Streams via Internet zu übertragen. Um den Datenverkehr zu minimieren muss ich dann schon zwangsläufig den Empfänger zielgerichtet ansprechen. Darum schrieb ich auch 'annähernd' verbindungslos, denn vollständig verbindungslos ist es eben nicht. Das ständige Lösen und Aufbauen der Verbindung betreibe ich nur, da während der Zeit der Inaktivität eine Verbindung nicht notwendig ist (Es kann durchaus sein, das mal 10 Min keine Daten gesendet werden). Warum also Ressouren verschwenden. Da nehme ich lieber die kurze Wartezeit des Auf-und Abbauens in Kauf.Mir fällt nur leider keine Methode ein bzw habe keine gefunden, die sicherstellt, das vor einem erneuten Senden der Indyclient auch tatsächlich disconnected ist.

MfG

Quitzlinga
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 27.09.07 21:15 
Moin!

user profile iconQuitzlinga hat folgendes geschrieben:
Das UDP-Protokoll ist für mich nicht so geeignet, da es komplett verbindungslos ist und die Datenpakete wirklich an jeden gesendet werden, selbst an die, die das nicht angeht.

Vorsicht: UDP <> Broadcast! :mahn: Du kannst selbstverständlich auch UDP-Unicasts machen. ;)

user profile iconQuitzlinga hat folgendes geschrieben:
Das ständige Lösen und Aufbauen der Verbindung betreibe ich nur, da während der Zeit der Inaktivität eine Verbindung nicht notwendig ist (Es kann durchaus sein, das mal 10 Min keine Daten gesendet werden). Warum also Ressouren verschwenden.

Wenn nur Resourcenschonung der Grund für deinen "TCP-verbindungslosen-Ansatz" ist, dann kann ich dich beruhigen: eine inaktive TCP-Verbindung kostet (praktisch) keine Resourcen. Deshalb also die "Verrenkungen" zu veranstalten, ist IMHO sinnlos. :D Lass die Verbindung halt einfach stehen und gut ist dat. :)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Quitzlinga Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 60
Erhaltene Danke: 2

Win XP
Delphi 2007 Prof. Codegear Win32
BeitragVerfasst: Do 27.09.07 21:29 
Hi

Ok, dann werde ich das Proggy mal wieder auf stehende Verbindungen umbauen. Ist zum Glück keine so grosse Arbeit. Und da die Verbindung ja keine Zeit kostet, ists am Ende vielleicht sogar besser. Auf jeden Fall danke noch mal für die Aufklärung. :D

MfG

Quitzlinga