Entwickler-Ecke
Delphi Tutorials - Binär-Protokoll-Tutorial (Sockets - Mal-Chat+Files)
Narses - Fr 06.04.07 12:04
Moin!
Hier die Version des im Tutorial entwickelten Mal-FileTransfer-Chats mit den neuen
TNBFPA-Komponenten [
http://www.delphi-forum.de/topic_71223.html], um mal ein konkretes Anwendungsbeispiel im Vergleich zu haben. ;)
Die Kompos werden hier allerdings nicht voll designgerecht verwendet, weil ich so nah wie möglich am Originalcode des Tuts bleiben wollte. :mahn: Dazu mehr im nächsten Tutorial mit den Kompos. :P
cu
Narses
//EDIT: Update des Quelltextes an die Kompo-Version 1.10 (
.Add(Buf,Len) ->
.AddBuf())
//EDIT2: Update des Quelltextes an die Kompo-Version 1.20 (Unicode-save)
alias5000 - Fr 13.04.07 00:30
Spontan ist mir in der kompilierten Demo ein Fehler aufgefallen:
Wenn ich mit einem Client bereits ein Bild angefangen habe zu malen und dann mit einem zweiten Client verbinde und malen will, wird das bereits begonnene Bild nicht an den neuen Client gesendet. Lässt sich manuell natürlich mit Bild komplett senden wieder ausgleichen.
Vielen Dank für deine Anstrengungen! Gerade das Binär-Protokoll Tutorial fand und finde ich sehr interessant, auch wenn ich nicht von meinem Zeichenkettenprotokoll weggehen werde ;) (hat aber auch seine Gründe, BenBE hatte da ja mal in nem Thread zu neulich recht aktiv mitdiskutiert, glaub mit dir und DGL-Luke)
Gruß
alias5000
Narses - Fr 13.04.07 01:29
Moin!
alias5000 hat folgendes geschrieben: |
Wenn ich mit einem Client bereits ein Bild angefangen habe zu malen und dann mit einem zweiten Client verbinde und malen will, wird das bereits begonnene Bild nicht an den neuen Client gesendet. Lässt sich manuell natürlich mit Bild komplett senden wieder ausgleichen. |
Das ist kein Fehler, das ist Design. ;) Ernsthaft, wird auch so im Tut beschrieben, da die Transferlast für das komplette Bild (wenn man´s dann auch noch in Farbe macht, ist das auch noch schlimmer!) recht hoch sein kann, wird das nur "auf Kommando" ausgeführt, damit die Serverlast nicht unnötig stark ansteigt, wenn man eine hohe Client-Fluktuation hat. :idea:
alias5000 hat folgendes geschrieben: |
Vielen Dank für deine Anstrengungen! Gerade das Binär-Protokoll Tutorial fand und finde ich sehr interessant, |
Danke für das Lob! :D
alias5000 hat folgendes geschrieben: |
auch wenn ich nicht von meinem Zeichenkettenprotokoll weggehen werde ;) |
Das habe ich weder erwartet noch bezwecken wollen. ;) (s.u.)
alias5000 hat folgendes geschrieben: |
(hat aber auch seine Gründe, BenBE hatte da ja mal in nem Thread zu neulich recht aktiv mitdiskutiert, glaub mit dir und DGL-Luke) |
Selbstverständlich gibt es immer gute Gründe für beide Ansätze (TermChar+CounterData), deshalb habe ich ja auch beide präsentiert, um für sich und den Zweck wählen zu können. :zwinker:
Naja, eigentlich hat
DGL-luke wohl eher "mit sich selbst diskutiert" (diplomatisch formuliert), was
BenBE mehr moderiert hat :mrgreen: auf das Niveau wollte ich mich nicht einlassen... :| (scheint jemand zu sein, der zwar keinen Beitrag zum Thema leisten kann ["...hab die Grundlagen grad nicht zur Hand..."], aber schonmal weiß, dass alle anderen Unsinn reden... :gruebel:)
cu
Narses
alias5000 - Fr 13.04.07 11:47
Narses hat folgendes geschrieben: |
alias5000 hat folgendes geschrieben: | Wenn ich mit einem Client bereits ein Bild angefangen habe zu malen und dann mit einem zweiten Client verbinde und malen will, wird das bereits begonnene Bild nicht an den neuen Client gesendet. Lässt sich manuell natürlich mit Bild komplett senden wieder ausgleichen. |
Das ist kein Fehler, das ist Design. ;) Ernsthaft, wird auch so im Tut beschrieben, da die Transferlast für das komplette Bild (wenn man´s dann auch noch in Farbe macht, ist das auch noch schlimmer!) recht hoch sein kann, wird das nur "auf Kommando" ausgeführt, damit die Serverlast nicht unnötig stark ansteigt, wenn man eine hohe Client-Fluktuation hat. :idea: |
Ja stimmt hast recht ;)
Wobei natürlich für eine konkrete richtige Umsetzung das dann schon irgendwie bewältigt werden sollte (also in einer "Produktivumgebung", wenn man das dann so nennen kann).
Aber daran kannste dann erkennen, wer die Demos manippuliert und wer aus dem Tutorial was eigenes entwickelt :mrgreen:
Narses hat folgendes geschrieben: |
alias5000 hat folgendes geschrieben: | auch wenn ich nicht von meinem Zeichenkettenprotokoll weggehen werde ;) |
Das habe ich weder erwartet noch bezwecken wollen. ;) (s.u.) |
Hatte ich ja mit nem Augenzwinkern gesagt, war nicht wirklich ernst gemeint
Gruß
alias5000
Neotracer64 - Fr 13.07.07 01:17
Wie könnte ich jetzt am einfachsten mit den Kompos Datenübertragungen zwischen Server <> Client realisieren?
Die TUserList verwirrt mich etwas, da dort der Server ja nicht drinsteht. Sonst habe ich nirgendwo InStream und Outstream gefunden. Ein Beispiel wäre ganz nett. :)
Danke schonmal im vorraus.
Narses - Fr 13.07.07 01:33
Moin!
Neotracer64 hat folgendes geschrieben: |
Wie könnte ich jetzt am einfachsten mit den Kompos Datenübertragungen zwischen Server <> Client realisieren? |
Sprichst du jetzt von den
TNBFPA-Komponenten [
http://www.delphi-forum.de/topic_71223.html] oder von den Socket-Kompos (TClient-/TServerSocket)? :gruebel: Abgesehen davon: es werden doch die ganze Zeit Daten zwischen Client und Server ausgetauscht. :nixweiss:
Neotracer64 hat folgendes geschrieben: |
Die TUserList verwirrt mich etwas, da dort der Server ja nicht drinsteht. |
Der Server ist eine transparente Vermittlungsstelle, deshalb macht es keinen Sinn, diesen als Ziel bzw. Endpunkt für irgendwelche Übertragungen vorzusehen. :mahn: Beispiel: Du schickst ja auch keine Daten (schlussendlich) an den ICQ-Server, sondern an einen anderen Benutzer. ;)
cu
Narses
Neotracer64 - Fr 13.07.07 03:34
Hi Narses,
Ich meine deine Komponente.
Es macht schon Sinn, wenn man als Server eine Datei an mehrere Clients oder nur an einen schicken möchte.
Von Client zu Server macht es schon weniger Sinn, aber ich hatte da so eine Art CVS Idee im Kopf, wo jeder seine Projekt-Dateien auch an den Server schickt, der sie dann verwaltet und mit anderen synchronisiert. Sozusagen als Sammelstelle.
Und komm mir nicht mit dem Argument ein anderes CVS System zu benutzen, dann sage ich dir benutze ein anderes Chat-Protokoll, wie das IRC. ;)
Ich möchte einfach nur ein bisschen rumspielen und mich weiterbilden.
Vlt. hast du eine Idee für mich, wie ich also einen Server <> Client DateiTransfer mit deinen Komponenten am besten hinbekomme?
Danke schonmal im Vorraus. :)
EDIT: Ahh, sorry. Jetzt versteh ich deine Antwort. Ich meinte Übertragungen von Dateien und habe Datenübertragungen gesagt. Entschudlige, ist schon spät. ;)
barrais - Mo 01.10.07 11:10
Hallo Narses,
ich versuche dein Protokoll-Adapter mit UDP von Indy zu realisieren(nachdem ich es aufgegeben habe, dein eigenen UDP Protokoll mit D5 zu compilieren!), das Problem ist das die Indy-UDP kein OnWrite Ereignis besitzen, kannst du mir vielleicht weiterhelfen?
Danke!
Narses - Mo 01.10.07 12:49
Moin!
barrais hat folgendes geschrieben: |
ich versuche dein Protokoll-Adapter mit UDP von Indy zu realisieren |
Ähm, ich glaube, ich habe dein "Problem" noch nicht richtig verstanden :gruebel: Du willst den in diesem Tutorial vorgestellten TCP-Protokoll-Adapter auf (Indy-)UDP umbauen? :shock: Das geht nicht; schlicht, deshalb, weil das im Tutorial verwendete Konzept TCP voraussetzt.
Es wird zwar grundsätzlich möglich sein, auch einen UDP-Protokoll-Adapter zu entwickeln, aber sicher nicht durch einen (wie auch immer gearteten) "Umbau" dieses Ansatzes hier. Das wird auf ein Neudesign hinauslaufen... :?
barrais hat folgendes geschrieben: |
(nachdem ich es aufgegeben habe, dein eigenen UDP Protokoll mit D5 zu compilieren!) |
Wenn ich es richtig gesehen habe, dann sollte sich der
TUdpSockUtil [
http://www.delphi-forum.de/topic_55339.html] auch unter D5 compilieren lassen, wenn du die Unit-Referenzen anpasst. Ich meine, in
einem der letzen Beiträge im entsprechenden Thread [
http://www.delphi-forum.de/viewtopic.php?p=458450#458450]sowas gelesen zu haben (kann auch über den Link in die DP gewesen sein).
barrais hat folgendes geschrieben: |
das Problem ist das die Indy-UDP kein OnWrite Ereignis besitzen, kannst du mir vielleicht weiterhelfen? |
Sorry, die Indy-Kompos sind leider gänzlich verschieden zu den Delphi-Sockets und auch zum TUdpSockUtil, deshalb kann ich dir da leider nicht helfen. :(
Was möchtest du denn machen? Vielleicht versuchst du ja, an der "falschen Stelle" anzusetzen? :nixweiss:
cu
Narses
barrais - Mo 01.10.07 13:21
hi,
ich habe vor, ein Anwendundungsprogramm zu implementieren, das Messdaten die über Ethernet ankommen speichert und präsentiert.Ich habe UDP ausgesucht, weil:
1. ich dadurch Broadcast Packete wegschicken kann
2. ich noch ein Mikrocontroller Programmieren muss, der diese Messungen durchführt; ein UDP-Stack ist einerseits relativ einfacher zu Programmieren und andererseits nimmt nicht viel Speicherplatz im Anspruch .
3. UDP viel schneller ist, vorallem wenn es um Grosse Datenmengen geht. und was Sicherheit angeht brauche keine Gedanken machen, weil ich das ganze in einem LAN-netz betreiben wird.
Hast du vielleicht eine Idee, wie man deinen Binären Protokoll-Adapter(übrigens: das Tutorial war sehr schön, Respekt!) auf UDP-Socket umbauen kann?
Danke!
Narses - Mo 01.10.07 15:36
Moin!
barrais hat folgendes geschrieben: |
3. UDP viel schneller ist, vorallem wenn es um Grosse Datenmengen geht. |
Das ist nicht wirklich korrekt :? Die Transferrate ist bei TCP auch nicht geringer, es gibt hier aber Timeouts, die zu beachten sind. :nixweiss:
barrais hat folgendes geschrieben: |
Hast du vielleicht eine Idee, wie man deinen Binären Protokoll-Adapter auf UDP-Socket umbauen kann? |
Wie schon gesagt, das wird nix, den Protokoll-Adapter wirst du nicht auf UDP "umbauen" können. Entscheidender Haken: du hast keinen TransferStream von der API, sondern nur Paketzustellung, also bleibt die ganze Sicherungsschicht an dir hängen. Aber, wenn ich deinen Anwendungsfall richtig einschätze, brauchst du das doch auch gar nicht. Deshalb wäre ein einfacheres, paketorientiertes Protokoll für dich möglicherweise viel besser geeignet. :idea:
barrais hat folgendes geschrieben: |
(übrigens: das Tutorial war sehr schön, Respekt!) |
Danke. :D
cu
Narses
barrais - Di 02.10.07 09:41
Hallo!
Zitat: |
Deshalb wäre ein einfacheres, paketorientiertes Protokoll für dich möglicherweise viel besser geeignet. |
Das hört sich sehr gut an!
hast du vielleicht zufällig ein Tutorial dazu geschrieben :roll: !
oder kennst du wo ich das finden könnte?
Vielen dank!
Moderiert von Narses: Quote-Tag repariert
Narses - Di 02.10.07 10:25
Moin!
barrais hat folgendes geschrieben: |
hast du vielleicht zufällig ein Tutorial dazu geschrieben :roll: ! |
Ich habe zwar ein UDP-Tut geschrieben (s.o. im Navigationsbereich), aber das erklärt eigentlich nur die Grundzüge. Wie du dein Protokoll entwirfst, ist natürlich etwas, das dir kein Tutorial zeigen kann - du musst schon selbst wissen, was und wie du das, was du machen willst, letztendlich umsetzt. :nixweiss: Hängt ja eben auch davon ab, was da passieren soll und welche Daten konkret transportiert werden müssen...
cu
Narses
Ravy - Fr 01.02.08 17:00
Ein dickes Lob an den Author des Tutorials. Es hat mir sehr weitergeholfen.
Vielen Dank
Ravy
der13geist - Mi 26.03.08 20:50
Titel: Kurtze verständniss frage
Moderiert von Narses: Aus Internet / Netzwerk hier angehangen am 26.03.2008 um 23:37 Uhr
Guten Tag
Habe hier mal eine kurtze verständniss frage. Ich arbeite grade das Biär Protokoll Tutorial von Narses durch.
Nur eine frage beantwortet mir das tutorial nicht, was aber eine grundlegenheit des tutorials darstell.
der Code schnipsel
Delphi-Quelltext
1:
| PInteger(@Buffer[1])^ := |
Also ich verstehe dies zwar aber warum wird das alles in den speicher geschrieben und nicht einfach
geschrieben ?
MfG
Der13Geist
BenBE - Mi 26.03.08 21:19
Benutze bitte Delphi-Tags für Source, wirkt etwas übersichtlicher ;-)
Zu besagtem Code-Schnipsel:
Durch den expliziten Typecast auf PInteger erzeugt man einen Zeiger, der auf einen Integer zeigt, der an der Stelle des Puffers platziert ist. Würde man hier einfach nur den Zugriff schreiben, so würde man auf einen Char zugreifen.
Was macht das konkret: Dadurch, dass man dem Compiler sagt, dass an besagter Speicherstelle ein Integer platziert werden soll, kümmert sich der Compiler darum, den Integer vollständig zu schreiben; man muss also nicht selber immer alles schreiben. Bei einem Char müsste man den zu schreibenden Integer erst Byte-für-Byte zerlegen und dann über den Puffer wieder korrekt zusammensetzten.
Kurz gesagt: Man erzwingt einfach eine andere Sicht des Compilers auf den Speicher ;-)
der13geist - Mi 26.03.08 21:31
Nur warum schreibt man es überhaupt in den speicher ?
BenBE - Mi 26.03.08 21:51
Buffer ist doch auch nur ein Bereich im Speicher. Und Speicher ist nix andres als ne riesig große Regalwand, wo man sich die Fächer so zusammenbauen kann, wie man se grad brauch ;-)
@Warum zuerst in den Speicher vor'm Senden: Müsste Narses eigentlich drin stehen haben ... Kann Dir aber mindestens 3 zusätzliche Gründe nennen:
- Geht schnell
- Datenbündelung
- Vermeidung kleiner Pakete
der13geist - Mi 26.03.08 22:04
nja also der Code heisst ja eig. so
Delphi-Quelltext
1: 2:
| SetLenght(BinMessage, 4); PInteger(@BinMessage[1])^ := Lenght(Edit1.Text); |
und (da ich es immer noch nicht verstanden habe) ich hätte anstatt so es so geschrieben
Delphi-Quelltext
1:
| BinMessage := Lenght(Edit1.Text); |
Aber dieses würde ja nicht funktionieren.
Habe es leider imer noch nicht verstanden :(
GTA-Place - Mi 26.03.08 23:42
Ähm... es steht doch dran warum:
1. BinMessage ist ein String
2. Die Länge des Strings soll im Binärformat in BinMessage geschrieben werden.
Delphi-Quelltext
1: 2:
| BinMessage := Length(Edit1.Text); BinMessage := IntToStr(Length(Edit1.Text)); |
Und auf Seite 9 noch einmal ganz exakt beschrieben.
der13geist - Do 27.03.08 00:05
AHSOOO
Also ist dieser code eig. nur dazu da die länge des strings in Binär format abzuspeichern !?
Narses - Do 27.03.08 00:21
Moin!
der13geist hat folgendes geschrieben: |
Also ist dieser code eig. nur dazu da die länge des strings in Binär format abzuspeichern !? |
Genau. ;) Das WARUM wird schon in Kapitel 2.3 auf Seite 6 erklärt: Rahmenbildung über Längenzähler :idea:
cu
Narses
der13geist - Do 27.03.08 00:28
aber würde ich es beim empfangen nicht in Hex umwandeln würde doch dort (Nun ja, angenommen in Edit1 steht "Hallo Welt") nur das stehen "#0#0#0#10" also dreimal ein Nullbyte und einmal ein Zeichen mit dem ASCII Code von 10 oder ?
Narses - Do 27.03.08 00:31
Moin!
der13geist hat folgendes geschrieben: |
aber würde ich es beim empfangen nicht in Hex umwandeln |
Das machen wir ja nur, um es überhaupt anzeigen zu können.
der13geist hat folgendes geschrieben: |
würde doch dort (Nun ja, angenommen in Edit1 steht "Hallo Welt") nur das stehen "#0#0#0#10" also dreimal ein Nullbyte und einmal ein Zeichen mit dem ASCII Code von 10 oder ? |
Nein, auch das wird in Kapitel 2.3 ausführlich erläutert: Intel-CPUs schreiben lsb-first, also steht dort: #10,#0,#0,#0. :idea:
cu
Narses
der13geist - Do 27.03.08 00:43
Danke mit diesen erkentnissen wird mir höchstwahrscheinlich alles klar. Ich werde dein tutorial noch einmal von anfang an durchlesen.
Ich danke für die Hilfe
MfG
Narses - Do 27.03.08 00:44
Moin!
Bitte, gern geschehen. :)
cu
Narses
Mann_aus_Delphi - Di 01.04.08 19:18
Titel: Ie bekomme ich überhaupt die korrekte IP?
Hey,
erstmal herzlichen Dank an Narses für das tolle Tutorial. :beer:
Ich habe fleißig gelesen und gebastelt, und getestet.
Auf meinem Lokalen Pc kann ich Verbindungen mit dem PC meines Bruders und dem meiner Mutter aufnehmen, jedoch nicht zu, sagen wir mal meinem Opa hundert Kilometer entfernt.
Ich schätze, dass die lokale IP dafür nicht taugt, aber welche dann? Die öffentliche geht auch nicht, zumindest zeigt er mir einen Verbindungsfehler an. Welche IP muss ich dafür nehmen, und wo bekomme ich sie her? :?: :?: :?: :eyecrazy: :dunce:
BenBE - Di 01.04.08 19:26
Dafür gibt es 2 Möglichkeiten:
1. Du nutzt ein VPN wie z.B. Hamachi. In dem Fall kannst Du dann die VPN-IP nutzen.
2. Ansonsten musst Du den entfernten Rechner (also der, der Server spielt) als DMZ konfigurieren (am Router) oder über Port-Forwarding (am Router) nach draußen "weiterleiten" ...
Zu zweiterem hat Narses auch bereits einen Beitrag geschrieben, wie das geht. Ersteres kann ich aus eigener Erfahrung empfehlen ;-)
Mann_aus_Delphi - Mo 14.04.08 14:28
Titel: Noch ne Frage...
Ich den Clienten und den Server jetzt etwas erweitert und würde ihn nun gerne veröffentlichen (natürlich mit Bezug auf diese Seite und Narses Protokoll). Wenn Ihr, vor allem Narses, nichts dagegen habt, würde mich das wirklich sehr freuen! :lol: :lol: :shock:
Mann_aus_Delphi
BenBE - Mo 14.04.08 16:23
Solang das Rahmen-Protokoll kompatibel ist (also die Basisstruktur in der Übertragung), seh ich da wenige Probleme ... Außerdem ist ein öffentliches Tut ja dafür gedacht, dass daraus auch neue Anregungen für andre entstehen ;-)
Narses - Do 17.04.08 13:15
Titel: Re: Noch ne Frage...
Moin!
Mann_aus_Delphi hat folgendes geschrieben: |
Ich den Clienten und den Server jetzt etwas erweitert und würde ihn nun gerne veröffentlichen (natürlich mit Bezug auf diese Seite und Narses Protokoll). Wenn Ihr, vor allem Narses, nichts dagegen habt, |
Klar habe ich nichts dagegen. ;) Dazu eignet sich die Sparte
Open Source Projekte [
http://www.delphi-forum.de/forum_Open+Source+Projekte_28.html], wenn du den Quelltext dazu tun willst (was ich hiermit vorschlagen möchte :zwinker:).
cu
Narses
Pseudo - Fr 10.08.12 20:54
Sorry, dass ich das hier ausgrabe (Tut mir echt leid!),
aber ich hätte da noch eine Frage:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TNBFPAServer.ServerSocket1ClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin LogIt('! SID:'+IntToStr(ServerPA.ConnectionsBySocket[Socket].SessionID)+ ' Fehler [WSA:'+IntToStr(ErrorCode)+'] aufgetreten! '+Socket.RemoteAddress); if (Socket.Connected) then Socket.Close else DeleteClient(Socket); ErrorCode := 0; end; |
Hier nutzt du zum Disconnecten die Funktion Socket.Close! Wäre es nicht eig. besser hier Die Disconnect Funktion vom PA zu nutzen? bei mir kommt es mit obigem Code manchmal zu einem Fehler O.o mit Disconnect klappts wie geschmiert :D
Moderiert von Martok: Delphi-Tags hinzugefügt
Narses - Sa 11.08.12 00:08
Moin!
Pseudo hat folgendes geschrieben : |
Sorry, dass ich das hier ausgrabe (Tut mir echt leid!),
aber ich hätte da noch eine Frage: |
Dazu ist der Thread da, kein Problem. ;)
Pseudo hat folgendes geschrieben : |
Hier nutzt du zum Disconnecten die Funktion Socket.Close! Wäre es nicht eig. besser hier Die Disconnect Funktion vom PA zu nutzen? bei mir kommt es mit obigem Code manchmal zu einem Fehler O.o mit Disconnect klappts wie geschmiert |
Man beachte: wir befinden uns bereits in der Fehlerbehandlung! :shock: Die spannendere Frage scheint mir eigentlich zu sein, wie es dazu kommt, dass du an dieser Stelle überhaupt die Notwendigkeit hast, die Verbindung noch trennen zu müssen (idR ist nach einem Fehler der Socket sowieso dicht oder zumindest unbrauchbar). Das Socket.Close ist da eigentlich nur noch Dichtmasse, normalerweise kommt man da gar nicht mehr hin. 8) :idea:
Aber, ich gebe zu :?, das Trennen der Verbindung im Server ist schon immer hakelig gewesen und im Nachhinein bereue ich es etwas, dass nicht per Message gelöst zu haben (es gibt da leider ein paar unschöne Probleme mit der MessageLoop, die kriegt man nicht anders in den Griff). :nixweiss:
Warum auch immer es noch (genau genommen nachträglich, weil schon in der Fehlerbehandlung) bei dir zu Fehlern kommt, die ein PA.Disconnect statt einem Socket.Close "heilt", mach es so. An der Stelle kann man eigentlich nicht mehr viel kaputt machen (die Verbindung ist dann sowieso kaputt, sonst wärst du nicht im ErrorHandler gelandet). ;)
cu
Narses
Pseudo - Mo 13.08.12 17:02
Ich hab den Ort jetzt gefunden :D
Wenn der Client mir was sendet und er genau dann per Taskmgr beendet wird kommt es (glaube ich) zu folgendem Problem:
Ich will die Instanz des PA zerstören, habe aber noch was in der Inbound Warteschlange...
Zumindest theoretisch könnte man ja einfach einen try-catch block um die komplette Procedur machen, weil das objekt danach ja eh zerstört wird, oder?
Übrigens danke für das geniale Tutorial, das hätte ich definitiv nicht ohne dich hinbekommen :D
Narses - Mo 13.08.12 17:55
Moin!
Pseudo hat folgendes geschrieben : |
Wenn der Client mir was sendet und er genau dann per Taskmgr beendet wird kommt es (glaube ich) zu folgendem Problem: |
Ja, so ungefähr hatte ich mir die Situation vorgestellt. ;)
warum auch immer man sowas machen sollte
Pseudo hat folgendes geschrieben : |
Ich will die Instanz des PA zerstören, habe aber noch was in der Inbound Warteschlange...
Zumindest theoretisch könnte man ja einfach einen try-catch block um die komplette Procedur machen, weil das objekt danach ja eh zerstört wird, oder? |
Mach´s mit einem PA.Disconnect oder per try-except, das spielt da alles keine Rolle mehr. :nixweiss:
btw: Lass mich raten, du programmierst sonst eher in PHP, oder? :zwinker:
Pseudo hat folgendes geschrieben : |
Übrigens danke für das geniale Tutorial, das hätte ich definitiv nicht ohne dich hinbekommen :D |
:beer:
cu
Narses
Pseudo - So 09.09.12 01:23
Falls man hier auch noch einen Tutorialwunsch äußern kann:
Wie kann ich den Server multithreaden (so, dass der ProtocolAdapter nicht komplett umgeschrieben werden muss)? Ich hab dazu bis jetzt nicht viel im Internet gefunden... Und die Indys kann ich nicht leiden (unter anderem auch weil man nur eine Zeile übertragen kann?!?). Würde mich freuen! Muss ja nicht lang sein, sondern nur kurz erklären wie man es überhaupt macht ;-)
Vielen Dank
Narses - So 09.09.12 13:58
Moin!
Pseudo hat folgendes geschrieben : |
Wie kann ich den Server multithreaden |
Kurz gesagt: gar nicht. :nixweiss: Was du aber machen kannst: den kompletten Server in einen eigenen Thread auslagern, diesen nur für die Kommunikation verwenden (dafür reicht die Performance alle mal aus, die eigentliche Arbeit macht eh die WSA) und die Daten an Client-Worker-Threads durchzureichen. :idea:
Der Schlüssel für einen eigenen Server-Thread (klar, am Besten mit dem
TNBFPAServer [
http://www.entwickler-ecke.de/viewtopic.php?t=71223]) ist der wirklich geradezu geniale
TMessageThread [
http://www.entwickler-ecke.de/viewtopic.php?t=90333] :beer: von
delfiphan.
Pseudo hat folgendes geschrieben : |
Ich hab dazu bis jetzt nicht viel im Internet gefunden... |
Das ist auch nicht verwunderlich. ;)
Theoretisch kann der TServerSocket auch Multithreading, aber ich habe es aufgegeben herausfinden zu wollen, wie man das machen muss. Ich blicke nicht durch, was die Entwickler sich damals dabei wohl gedacht haben... :?!?:
Gibt es jemanden, der das jemals geschafft hat? Wenn ja, bitte unbedigt bei mir (oder hier) melden! :lupe:
Pseudo hat folgendes geschrieben : |
Und die Indys kann ich nicht leiden (unter anderem auch weil man nur eine Zeile übertragen kann?!?). |
Zunächst mal: selbstverständlich kann der Socket-Wrapper (IOHandler oder so heißt das dort) der Indies auch mehr als "eine Zeile" senden (du kannst ja auch mit Streams arbeiten), aber du scheinst da was mit den Methoden zur Unterstützung von zeilenorientierten Protokollen nicht verstanden zu haben. :zwinker:
Leider muss ich aber sagen: wenn du einen "echten" Multithreaded-Server in Delphi haben willst, schätze ich ist der TidTCPServer vermutlich alternativlos. :nixweiss:
cu
Narses
Pseudo - So 09.09.12 15:12
Also ich kann veröffentlichen was ich bisher rausgefunden habe (wenig...):
Es gibt eine GetThread Procedure in der Server Komponente,
sie hat als einen "var"-Parameter (also ein call by reference) einen "TServerClientThread",
diesen muss man selbst coden (also per Thread Klasse)...
Mehr auch nicht...
Pseudo
EDIT:
Ich hab noch mehr rausgefunden, und werde vlt. wenn ichs hinkriege ein Tutorial dazu erstellen, aber ich würde gerne wissen, was die Borland Entwickler beim entwickeln der Komponente genommen haben O.o
Pseudo
Schwedenbitter - Do 08.12.16 16:29
Also mal völlig an den letzten Themen vorbei :wink: :
Ich bin gerade damit befasst, anhand des Tutorials das ganze für die Indys nachzubauen. Scheinbar ist es mir gelungen, über Umwege endlich auch einen
AnsiString binär zu übertragen. Jetzt stehe ich aber vor folgendem "Problem":
Da Delphi ja (hoffentlich) nicht ohne Grund der Windows-Welt gefolgt ist und - sofern ich das richtig verstanden habe - WideString als Standard benutzt, möchte ich die mit reinbasteln - und das betrifft auch die
NarsesBFPA.pas.
Bevor ich nun stundenlang durch Versuch und Irrtum eine Lösung finde, frage ich mal, ob folgender Code tendenziell funktionieren sollte:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Procedure TCmdSeq.Add(Const Value: AnsiString); Begin Add(PAnsiChar(Value)^, Length(Value)); End;
Procedure TCmdSeq.Add(Const Value: String); Begin Add(PChar(Value)^, Length(Value) * SizeOf(Char)); End; |
Gruß, Alex
Narses - Fr 09.12.16 17:12
Moin!
Schwedenbitter hat folgendes geschrieben : |
Bevor ich nun stundenlang durch Versuch und Irrtum eine Lösung finde, frage ich mal, ob folgender Code tendenziell funktionieren sollte: |
Ich rate dringend davon ab, den hier gezeigten Ansatz (konkret: Strings als binärer Datencontainer) in Delphi-Versionen >7 zu verwenden! Dieser "Trick" (Ausnutzen der String-Compiler-Magic) funktioniert nur bis D7, so ist das Leben. Oberhalb von D7 sind meine Tutorials nur noch als Ideenquelle nutzbar. :nixweiss:
cu
Narses
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!