Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi IdTCPClient: Software caused connection abort. (https://www.delphipraxis.net/73128-idtcpclient-software-caused-connection-abort.html)

alleinherrscher 12. Jul 2006 20:27


IdTCPClient: Software caused connection abort.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi@all!

(vielleicht hi, datacool, vielleicht kannst gerade du mir was helfen, du bist ja echt DER Experte hier was Indy TCPServer angeht)

Folgendes Problem:

Ich bastle gerade an einem Programm welches Datenpackete (als Stream) per Indy versenden kann.
Nix ungewöhnliches also. Das Programm soll Textnachrichten, Dateien und Bilder verschicken können.
Nun hab ich mir ein Format gebastelt aus dem ein Memorystream erzeugt wird welcher versendet wird.

Das klappt soweit auch problemlos, allerdings dachte ich mir, dass es praktisch wäre, eine Art "Warteschleife" einzubauen, so wie bei einem Drucker. Wenn eine Dateien z.B. von Computer A an Computer B gesendet wird, und man von Computer A wärend dessen an Computer C senden möchte, speichert er sich den Stream so lange bis das Senden an Computer B beendet ist.

Dabei entsteht natürlich folgendes Problem: Ich schicke die Daten immer von Client zum Server, und mein Programm muss mitbekommen, wann eine Verbindung (in unserem Beispiel die Verbindung von Computer A zu B) beendet ist, damit direkt danach eine Verbindung (von Computer A nach Computer C) aufgebaut werden kann.

Nun wie realisiere ich das? Ich hab schon mehrere Varianten versucht:

1. OnDisconnect Event -> neue Verbindung aufbauen
2. OnWork -> falls Status=hsDisconncted ist -> neue Verbindung aufbauen
3. Timer -> falls TCPClient.connected=false -> neue Verbindung aufbauen.

Leider funktioniert keine der Möglichkeiten.

Es wird immer dieser Fehler verursacht:

"Software caused connection abort"

Ich hänge das entsprechende Programm einfach mal an

Wäre super, wenn ihr was wüsstet, z.B. DataCool! Ich glaub an dich!!!! Du bist Deutschland...öhm oder so...

Viele Grüße

DataCool 13. Jul 2006 09:37

Re: IdTCPClient: Software caused connection abort.
 
Hi,

erstmal danke für die Anerkennung *lol*

Erstmal muss ich vorweg sagen, das ich mit Delphi6 und Indy9 arbeite und Du verwendest Indy10.
Aber das sollte nicht das Problem seien, die Logik zu analysieren.

Ich habe jetzt gerade Deine Source-Code überflogen und dabei habe ich einige Sachen gefunden die ich anders machen würde(besser liegt ja im Auge des Betrachters ;-))

1. Die Idee mit der Que ist ja nicht schlecht, aber warum bastelest Du die so ein kompliziertes Konstrukt ?
Warum arbeitest Du nicht mit TList, TObjectList oder TThreadList ?
Dort hast Du schon eine fertige Klassen die Listen jeglicher Art verwalten. TThreadList ist sogar schon Threadsafe!

2. Bei Button Click fügst Du 5 mal die gleiche Datei für den gleichen Server in die Que warum ?

3. Anstatt des Timers solltest Du auf jeden Fall mit einen Thread arbeiten.

4. Warum die ganzen globalen Variablen ? Die gehören in die Hauptklasse.

Zu Deinem Hauptproblem:

Da ich leider kein Indy10 installiert habe kann ich das ganze leider nicht debuggen sondern nur tippen.
Du schreibst/schickst beim Write die Größe des Streams mit und beim Read liesst Du erst die Größe des Streams aus und liesst dann exakt die Anzahl von Bytes in den Stream. Das kann so richtig seien, aber in Indy9 muss ich wenn ich die Byte Größe des Streams mitgeschickt habe beim Lesen vorher nicht die Größe mitauslesen, das hat Indy automatisch gemacht. Du könntest in Deinem Fall bis zum Disconnect Lesen, den Dein Server liesst ja immer nur Daten und danach wird disconnected.

Also, ich würde eine komplette Klasse schreiben die alles was mit dem Client zu tuen hat verwaltet.
Innerhalb dieser Klasse würde ich eine Unterklasse schreiben die von TThread Abgeleitet ist und Deine "Abarbeitungsliste" in TThreadlist verwaltet.
Im Execute des Thread würde ich dann prüfen ob gerade Elemente in der Liste vorhanden sind, wenn ja das erste Element aus der Liste Lesen, aus der Liste entfernen und zum Server schicken.
Wenn er fertig ist mit verschicken das ganze wieder von vorne, also ne schleife drum machen ;-)

Hoffe das ganze hilft Dir ein wenig weiter, mehr kann ich leider ohne Indy10 und Höhere Delphi Version nicht sagen.

Gruß Data

alleinherrscher 13. Jul 2006 12:24

Re: IdTCPClient: Software caused connection abort.
 
Hi Data!

Danke für deine schnelle Antwort!!!

Erstmal: (und damit zu 2) Das Hauptformular ist ja nur ein Testprogramm für die Klasse. D.h. mit dem 5 mal in die Liste einfügen möchte ich nur simulieren, dass während des Sendens 4 weitere Elemente schon in der Liste sind...d.h. damit auch wirklich eine Listenabarbeitung erfolgt. ;) Das wird natürlich hinterher im richtigen Programm anders sein...ist also nur ein Test...

zu 1) Dieses Komplizierte Konstrukt lehrte man uns an der Uni, und da ich mich mit Tlist etc. nicht so recht auskenne, aber mit diesen Pointergeschichten schon relativ viel gearbeitet hab, finde ich sie ganz praktisch :)

zu 3) Wie kann man das mit dem Thread realisieren? Beim Server gibts ja diese schöne Funktion, dass ein Synchronisierter Thread erstellt werden soll, aber beim Client?!

zu 4) da gebe ich dir vollig recht, es sind viel zu viele globale Variablen. Allerdings habe ich z.B: folgendes Problem. In Indy7 konnte man (glaube ich) beim Thread.synchronize(Procedure) eine Procedur angeben die auch Parameter haben darf. Das habe ich hier auch versucht, aber der Compiler meckert immer ... d.h. ich darf scheinbar nur eine Procedure angeben, ohne Parameter. daher muss ich leider den Stream global einlesen um ihn dann in der Procedure "HandleReceivedStream" weiterzubehandeln...ich versuche das noch ein bisschen zu optimieren ;) Allerdings glaub mir: Ich war "scheiße froh", als das mit dem "HandleReceivedStream" endlich geklappt hat.

Zum Thema "Größe vom Stream mitschicken": Ich werde das mal versuchen, danke für den tipp, aber ich glaube nicht, dass das was mit dem eigentlichen Problem zu tun hat, denn: Wenn man immer nur ein Element in der Liste hat, also niemals direkt 2 hintereinander geschickt werden, funktioniert das Versenden ja reibungslos!

Ich habe das gefühl, dass die Variable TIdTCPClient.Connected nicht anständig funktioniert....kann das jemand bestätigen? Die scheint nicht direkt auf True zu gehen wenn eine Verbindung besteht und nicht auf false wenn die Verbindung getrennt wurde...

@Data: Kannst du mir ein paar Tipps zu dem Thread-programmieren geben? evtl (wenns nicht zu viel arbeit ist, ein paar schnipsel code oder so) ;) wenn "wir" das hinbekommen, wirst du auch lobend erwähnt :D


Grüße,
Alleinherrscher

DataCool 13. Jul 2006 12:52

Re: IdTCPClient: Software caused connection abort.
 
Hi,

Du hast ne PN !!

Und wenn Du das an der Uni wirklich so gelernt hast und du das immer so verwendest
dann hast Du viel Arbeitszeit unnötig verschwendet *lol*

Schau Dir TList, TObjectList und TThreadList an.

Bei allen handelt es sich um Klassen wo Zeiger in einer verketteten Liste komplett verwaltet werden.
TList verwaltet einfach eine verkettete Liste von Zeigern.
TObjectList verwaltet eine Liste von Objekten arbeitet aber intern auch mit Zeigern, zusätzlicher Vorteil man kann über Eigenschaften der Klasse einstellen ob TObjectlist sich um das Freigeben des Speichers der Objekte in der Liste kümmern soll.
TThreadList ist das gleiche wie TList nur das ganze Thread safe, hast Du also verschiedene Threads die alle die gleiche Liste benutzen müssen, dann verwende TThreadList.

Hoffe das Bsp. was ich Dir per PN geschickt habe, hilft Dir weiter.
Ansonsten musst Du Dich bei mir per TelWell melden(Nummer 1011 Nick DataCool).

Gruß Data


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:29 Uhr.

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