Autor Beitrag
tmtmtm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Fr 28.07.06 18:42 
Hallo Leute,

ich habe mal eine Frage zum Thema Netzwerk.
In Delphi gibt es ja die Komponenten "TServerSocket" & "TClientSocket".

Mein Problem betrifft insbesondere den Client-Socket.
Das Ziel soll es sein, innerhalb einer Prozedur den Request an den Server zu schicken, und dann auch den Reply noch in der gleichen Prozedur auswerten zu können.
Da nützen Ereignisse OnClientRead usw. relativ wenig. Denn diese rufen sich ja als Extra-Threads außerhalb der Prozedur auf, sobald die Entsprechende Message den Socket erreicht.

Wie kann man also das Senden & den Empfang serialisieren???

Ich habe es schon mit abgeleiteten TThread-Klassen versucht, und dafür eine Prozedur zu schreiben, die auf den Wert einer Boolean-Variable wartet, die im Ereignis "OnClientRead" auf True gesetzt wird, wodurch dann die Thread-Prozedur merkt, dass sie sich beenden kann.
Im Hauptthread warte ich dann nach dem Senden des Requests auf die Beendigung des Threads, den ich vor dem Aufruf der Sendeprozedur startete. Aber dabei blockiert der Hauptthread anscheinend derartig, daß in ihm keine Ereignisse des Clients mehr ausgewertet werden können.

Dann habe ich auch noch -weils also überhaupt nicht ging-, versucht CriticalSections zu nutzen. Habe ich die richtig verstanden?

CriticalSections nützen, um kritische shared resources zwischen mehreren Threads nutzen zu können, indem man mit EnterCriticalSection(Section:TRTLCriticalSection) "Unit=>syncobjs" die Section betritt, sofern sie nicht vorher durch einen parallelen Thread betreten wurde. Wenn dem so ist, sollte EnterCriticalSection ja nicht fortfahren, und stattdessen solange mit der weiteren Ausführung warten, bis LeaveCriticalSection(Section) von dem Thread aufgerufen wird, der die EnterCS & LeaveCS eingebettete Resource bis dahin in Gebauch hatte.

Doch bei mir geht das irgendwie von Grund auch nicht.

Ich sage:

ausblenden Delphi-Quelltext
1:
2:
3:
InitializeCriticalSection(Section);
EnterCriticalSection(Section);
EnterCriticalSection(Section); // Normalerweise Deadlock???


Aber es lockt nicht dead.

Was ist falsch? Habe auch zum Testen des Sacherhaltes schon mal mit Timern gearbeitet. Diesen Timern habe ich dann einfach eine globale CriticalSection-Variable zu fressen gegeben.

Im einen Timer: Delay: 1000ms

ausblenden Delphi-Quelltext
1:
2:
3:
4:
Timer1.Enabled:=False;
EnterCriticalSection(Section);
ShowMessage('Test1');
LeaveCriticalSection(Section);


Im anderen Timer: Delay: 5000ms

ausblenden Delphi-Quelltext
1:
2:
3:
4:
Timer2.Enabled:=False; // Nur einmal ausführen.
EnterCriticalSection(Section);
ShowMessage('Test2');
LeaveCriticalSection(Section);

Das Problem:
Nichts geht, wie es soll.
Wenn ich jetzt beide Timer im Hauptthread der Anwendung auf Enabled setze, dann kommt zuerst die Ausgabe "Test1". -Soweit ganz supertollokay- Dann klicke ich aber in der Message nicht OK. Sondern warte noch 4 Sekunden. Der erste Thread steht also immer noch bei ShowMessage('Test1'); Doch dann poppt aufeinmal doch "Test2" auf.
Das dürfte doch gar nicht gehen!!! Denn die Section ist ja noch durch den ersten Timer-Thread belegt. Wieso geht das?

Wie serialisiert ihr den Empfang der Geschichte hier??

Dankeschön für eure Tipps.

Gruß TMTMTM

Delphi 5 Enterprise 1701-D
W2K

Moderiert von user profile iconmatze: Delphi-Tags hinzugefügt
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 28.07.06 18:48 
Moin!

user profile icontmtmtm hat folgendes geschrieben:
Mein Problem betrifft insbesondere den Client-Socket.
Das Ziel soll es sein, innerhalb einer Prozedur den Request an den Server zu schicken, und dann auch den Reply noch in der gleichen Prozedur auswerten zu können.
Da nützen Ereignisse OnClientRead usw. relativ wenig. Denn diese rufen sich ja als Extra-Threads außerhalb der Prozedur auf, sobald die Entsprechende Message den Socket erreicht.

Das siehst du leider komplett falsch, das ist lediglich ereignisgesteuert im Hauptthread der Anwendung. ;) Selbst der TServerSocket macht das so, wenn man ihm nicht eine eigene Thread-Klasse unterschiebt. :|

user profile icontmtmtm hat folgendes geschrieben:
Wie kann man also das Senden & den Empfang serialisieren???

Schau mal hier rein, damit solltest du weiter kommen. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
tmtmtm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Fr 28.07.06 23:04 
Titel: Leider nicht ganz das, was ich brauche. Aber Dankeschön.
Hallo Narses,

danke für deine Antwort.
Das sind ein paar sehr gelunge Tutorials.
Ich freue mich immer wieder, wenn Leute sich abmühen um anderen zu helfen, und dabei noch was ordentliches rauskommt.

Aber leider ist es nicht (ganz) das, was ich brauche.

Anforderungsdefinition:

Ich versuche eine Abstraktion der Ereignisbehandlung von TClientSocket auf eine einfach zu handhabende Funktion. Am besten wäre es, die Daten aus dem Netzwerk in etwa so einfach zu bekommen, wie bei dem Auslesen einer Datei:

Function Transaction(Request:String;Var Reply:String):Boolean;

Analog z.B.: read(F,S);

Damit könnte ich was anfangen, da mir die Ereignisbehandlung mein komplettes prozedurales Konzept durcheinanderschmeißt.


Nachdem ich jetzt in einer halben Stunde einen kompletten, möglichen Lösungsansatz über 2 DIN-A4-Seiten in meinen Browser gezimmert habe, ist mein toller IE6.01 abgestürzt, als ich die Sache abschicken wollte.
Jetzt habe ich keine Lust mehr. Aber ich schreibe vielleicht morgen nochmal.

Der Lösungsansatz bestand auf alle Fälle über die Abkapselung der datenverarbeitenden Funktionen in einen seperaten Thread. Damit der Hauptthread der Anwendung mit dem TClientSocket weiterlaufen kann, und auf eintreffende Messages reagiert.
Dazu aber morgen mehr. Ich bin guter Dinge, daß es klappt, da ich den ganzen Mist hier jetzt schon zum 2. Mal durchkauen muss - Wegen meinem tollen Explorer.

Bis dahin schon mal schönes Wochenende.

CU


TMTMTM

PS: Wenn bis dahin noch jemandem die Rahmenbedingungen für CriticalSections einfallen, und weiß was da bei meinem obigen Thread nicht hinhaut möge gerne ein paar Zeilen schreiben. Das wäre sehr erfreulich. ;-)