Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TCPClient Problem (https://www.delphipraxis.net/104000-tcpclient-problem.html)

Vampyr09 25. Nov 2007 23:34


TCPClient Problem
 
Guten Tag. :hi:

Also, folgendes Problem:

Ich habe vor, einen kleinen Chat zu programmieren, weil ich denke, dass man sich damit wunderbar in die ganze
Materie des Netzwerkprogrammierens hineinversetzen kann.
Nur hängt es zur Zeit daran, dass mein Client einfach abschmiert.

Ich meine, die Verbindung zwischen idTCPClient und idTCPServer klappt schon ganz gut. :stupid:

Naja..wie schon gesagt, das Problem liegt daran, dass man etwas im Client schreibt, dass dann an den Server übertragen wird, allerdings, wenn der Server es zurückübertragen will, dann hängt der Client sich auf.

Server:

Delphi-Quellcode:
procedure TForm1.TCPServerExecute(AThread: TIdPeerThread);
var Text: string;
begin
  with AThread.Connection do
    begin
      Memo1.Lines.Add(ReadLn);
      text := ReadLn;
      WriteLn(Text);
      disconnect;
    end;
end;
Client:

Delphi-Quellcode:
procedure TForm1.BSendenClick(Sender: TObject);
begin
  with TCPClient do begin
    connect;
    try
      WriteLn(EText.Text);
      Memo1.Lines.Add(ReadLn);
    finally
      disconnect;
    end;
  end;
end;
Ich hoffe ihr könnt mir helfen, ihr seid immerhin hier die Pro´s :love:

:edit:

Delphi-Quellcode:
Memo1.Lines.Add(ReadLn);
Dort beschwert sich Delphi zumindest und sagt mir im Client garnichts mehr.
Ich schätze mal, ich hab da irgendwo ne endlosschleife weil er nicht disconnected, kann das hinhaun?

:/edit:

Vampyr09 26. Nov 2007 18:59

Re: TCPClient Problem
 
Okay..ich habe meinen Fehler gefunden.

Ich muss im Server schreiben:

Delphi-Quellcode:
procedure TForm1.TCPServerExecute(AThread: TIdPeerThread);
var text: string;
begin
  with AThread.Connection do
    begin
      text := readln;
      Memo1.Lines.Add(text);
      WriteLn(text);
      disconnect;
    end;
end;
Weil man kann nur einmal den Wert mit ReadLn auslesen. Also muss man ihn halt vorher in eine Variable schreiben.
:cheers: Man wird halt nur schlauer. :dancer:

Vampyr09 26. Nov 2007 20:17

Re: TCPClient Problem
 
Hmmpf... :gruebel:

Irgendwie hab ich doch noch ein paar Probleme damit. Und vielleicht antwortet mir ja jetzt mal jemand :mrgreen:
Und zwar:

Da nun ja nun schon der Client auf den Server zugreifen kann und alles. Klappt ja schonmal das, dass der Client seine
eigene Nachricht sieht. Aber darum geht es ja leider nicht bei einem Chat.

Jetzt habe ich mir überlegt, man muss ja nun nur alle paar Millisekunden beim Server überprüfen, ob es neue Nachrichten gibt. Dazu habe ich mir einen Timer genommen:

Delphi-Quellcode:
procedure ...Timer1....
begin
  With TCPClient do begin
    connect;
    try
      Memo1.Lines.Add(ReadLn);
    finally
      disconnect;
    end;
  end;
end;
Bei dieser Procedure schmiert aber der Client ab.


Also bin ich jetzt am Überlegen, ob man es nicht praktischer machen kann. Denn mit einem Timer hat man ja sowieso das Problem, dass Nachrichten verloren gehen können. Wenn man den Timer zum Beispiel auf 1 Sekunde stellt und in der einen Sekunde schreiben 2 Leute eine Nachricht, dann empfängt der Client ja nur eine der beiden Nachrichten.
Deshalb müsste man es ja schaffen, dass der Server dem Client mitteilt, dass eine neue Nachricht gekommen ist. Und der Client daraufhin die Nachricht vom Server verlangt.

Aber ich habe keine Ahnung, ob mein Ansatz richtig ist. Geschweige denn, wie ich diesen Ansatz fortführen kann.

Könntet ihr mir helfen? :kiss:

Namenloser 26. Nov 2007 20:20

Re: TCPClient Problem
 
Ich glaube du hast da einen Denkfehler. ReadLn hält das Programm automatisch so lange an, bis eine neue Zeile eingetroffen ist. D.h. du kannst dir den Timer sparen.

Vampyr09 26. Nov 2007 20:26

Re: TCPClient Problem
 
Aber ich muss doch meinem Client den Hinweis geben, dass er beim Server neu überprüfen soll ob es neue Nachrichten gibt oder?
Also muss ich es doch so machen, dass der Server dem Client den Hinweis gibt, dass es eine neue Nachricht gibt.

Bzw. der Server sollte sofort bei einer neuen Nachricht, die Nachricht an alle Clients senden

Richtig?

Hmmm...dann muss ich mir morgen mal den Kopf darüber zerbrechen wie ich das Problem lösen kann. :stupid:

Namenloser 26. Nov 2007 22:03

Re: TCPClient Problem
 
Der Unterschied ist: Es wird nicht geprüft, ob es neue Nachrichten gibt, sondern gewartet, bis es eine neue Nachricht gibt.

Vampyr09 27. Nov 2007 15:30

Re: TCPClient Problem
 
Das würde ja theoretisch bedeuten, dass ich auf dem Client auch die idTCPServer-Komponente setzen müsste um dann auch vom Server auf den Client connecten zu können.
Nur damit kommt ja dann wieder das Problem auf, dass es niemals im Internet arbeiten würde.

Seh ich das richtig? :cat:

:edit:
Mir ist da grad noch ne andere Möglichkeit eingefallen. Man könnte ja auch die IP-Adressen der Leute einlesen und speichern, die sich grad angemeldet haben. Und löschen, wenn sie sich ausloggen. Und dann somit wenn man eine Nachricht erhält an alle IP-Adressen die Nachricht schicken.

Welche Möglichkeit ist besser? :freak:

Oder sind beide nicht so toll. Dann gebt mir bitte nen anderen Lösungsvorschlag. :stupid:

:/edit:

wicht 27. Nov 2007 18:34

Re: TCPClient Problem
 
Das würde man vielleicht so machen, wenn man UDP benutzt (glaube ich).
Hast du dir mal die Beispiele angeguckt? Kenne mich mit den Indys nicht so aus, da ich ICS benutze, Aber du musst doch eigentlich mit den Clients nur zum Server verbinden und der behandelt die Clients im OnExecute glaube ich. Da ließt du dann immer eine Zeile vom Client aus und kannst an die Clients dann über irgendeine Eigenschaft (IdTCPServer1.Clients.Send() oder so ähnlich) Daten vom Server aus versenden.
Vom Prinzip her müsste es das eigentlich sein....

HTH

Vampyr09 27. Nov 2007 19:12

Re: TCPClient Problem
 
Schön wär es, wenn es so funktionieren würde.
Aber bei Indy´s arbeitet er so:
  • Der Client gibt an den Server ne Anfrage und wartet darauf, etwas vom Server per ReadLn einzulesen.

    -> Der Server führt OnExecute aus und schreibt per WriteLn eine Nachricht, welche dann der Client sofort per
    ReadLn einliest und ausgibt.

Und genau da kommt mein Problem, weil ich nämlich theoretisch ständig vom Client aus Anfragen stellen müsste an den Server.
Und ich stell mich irgendwie zu dumm dabei an.
Denn per Timer stürzt halt der Client ab.

=> Ich kam ja schon zu dem Schluss, dank "NamenLozer", dass ich sofort, wenn der Server eine neue Nachricht kriegt, diese Nachricht an den Client senden muss. Also müsste ich ja theoretisch auf dem Server ne idTCPClient-Komponente und auf dem Client ne idTCPServer-Komponente setzen, damit er das sofort macht.

Aber ist das so der richtige Weg, wenn es denn später vielleicht auch mal im Internet funktionieren soll?

wicht 27. Nov 2007 20:18

Re: TCPClient Problem
 
Ich glaube ich habe dein Problem jetzt verstanden :wink: ..
Irgendwie sieht das wirklich komisch aus mit der Komponente... In den Demos ist das mit einem Thread gelöst. Der Thread ließt einfach die ganze Zeit der Reihe nach alle Daten aus, bereitet sie auf und leitet die Sachen über Synchronize() an die Form weiter. Ob das so schön ist.. Man kann mit dem Client auch so ein TIdConnectionIntercept und TIdIOHandler verbinden, das Intercept-Ding hat auch einen Read-Event, der bei mir aber irgendwie nicht getriggert wird. Vielleicht habe ich auch was falsch gemacht. Naja, zum Schluß des Postings weise ich nochmal auf die ICS Komponenten hin, wenn dir das hier auch zu viel wird. Aber das ist nur meine eigene Präferenz und nur so als kleiner Tip nebenbei gemeint :wink: ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:27 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz