Autor Beitrag
Marco D.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Sa 12.11.05 21:38 
Also ich hab das Gefühl dass wenn man gleichzeitig (oder kurz nacheinander) strings per serversocket an den clientsocket schickt mit sendtext dass dann die beiden strings irgendwie vermischt ankommen. Irgendwo hatte ich mal gelesen, dass es eine Methode namens 'Write' gibt, bei der das nicht vorkommt, aber diese habe ich bis jetzt noch nicht gefunden. Meine Frage ist, wo es diese gibt.

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: So 13.11.05 10:19 
Das ist Blödsinn. Alles was du mit dem Socket sendest wird irgendwie geteilt hinten wieder rauskommen beim Empfänger. Dabei ist nur die Reihenfolge der Daten gewährleistet, nicht aber deren Unterteilung. Wenn du einen String sendest und du ein Netz mit sehr viel Traffic, dann kann es auch schon dazu kommen, das der String erst 4 oder 5 Aufrufen von OnClientRead komplett empfangen wurde. Es gibt nirgendwo eine Garantie, dass der String so abgetrennt wieder empfangen wird wie er losgeschickt wurde. Trenne dich von diesem Gedanken. Wenn du definierte Dinge brauchst, dann musst du dir ein eigenes Protokoll ausdenken, welches das regelt. Die Sockets sind reine Datenübertrager und dabei interessiert es nicht wie und womit welche Art von Daten in welcher Menge und/oder Grösse bei ihnen in den Puffer kommen. Sie versenden einfach stupide die Bytes und gut ist.

SendText ist nur eine Vereinfachung für Strings und macht nix anderes wie Write: Es schreibt die Daten in den Sendebuffer. Keine Methode sorgt sich um die Integrität der Daten als Block.

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: So 13.11.05 15:41 
Also ich will ja den Bildschirminhalt im Netzwerk versenden. Da sende ich per TCP Client /Server einerseits einen JPEG-Screenshot jede Sekunde. Ausserdem alle 400 milliesekunden per Socket die Mauskoordinaten und dann noch den Befehl 'click#left' wenn ein Linksklick ausgeführt wurde. Das Prob ist halt dass da irgendwelcher Buchsstabensalat rübergesendet wird und dann halt nix funktioniert. Ist es denn so einfach nen eigenes Protokoll zu schreiben? Wohl kaum.
Vielleicht sende ich zuviele Daten gleichzeitig

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: So 13.11.05 15:51 
user profile iconKoller hat folgendes geschrieben:
Das Prob ist halt dass da irgendwelcher Buchsstabensalat rübergesendet wird und dann halt nix funktioniert. Ist es denn so einfach nen eigenes Protokoll zu schreiben? Wohl kaum.
Vielleicht sende ich zuviele Daten gleichzeitig


1. Du kannst nicht zuviel gleichzeitig senden, da es linear in den Puffer eingereiht wird.
2. Du weisst doch auf der Gegenseit gar nicht wann was ankommt und wieviel von jedem. Es kann doch einfach nur unsynchron werden und schon hast du verloren. So lange du keine Synchronisation (was eni Protokoll erledigen kann) drinne hast, kann und kommt es immer wieder zu Buchstabensalat.
3. Ein Protokoll ist einfach. Schicke vor jedem Datenpacket immer ein kleines Packet (Record z.B.) vorne weg. Dieser Record enthält 2 Dinge: a) die grösse der Daten zu diesem Info Block der nach dem Record folgt und b) die Art des Blockes (Click Info, Mauskoordinaten, etc). Damit weisst du beim Client immer sofort wann ein Packet fertig empfangen wurde um es auszuwerten und zum anderen weisst du bei unbekannten Packeten wie man sie überspringt, da du die Länge kennst. Somit ist der Buchstabensalat auch hinfällig.

Du könntest auch noch in diesen Record vor den Daten (nennen wir ihn Header) noch einen konstanten Wert einbauen - damit könntest du dann den Transport synchronisieren, falls beim Client doch nur noch Müll ankommt. Dann musst du einfach so lange lauschen, bis mal wieder dieser Konstante Wert übertragen wurde und damit weisst du dann auch sofort wo der Header anfängt und aufhört. Aber ich denke nicht, das dies nötig wird.

Grundsätzlich musst du bei dem OnClientRead die im Empfangsbuffer enthaltenen Daten in einen Puffer bei dir aufnehmen - das aber nicht exklusiv sondern immer hinten anhängen. Nach dem Empfangen und anhängen kannst du dann die Daten verarbeiten. [1>] Das bedeutet so lange der Puffer mindestens so gross ist wie ein Header, diesen auslesen. Wenn der Puffer mindestens so gross ist wie der Header und der im Header angegebenen folgenden Datengrösse, dann kannst du einen Header samt Daten aus dem Puffer auslesen und verarbeiten. Danach den Teil vorne aus dem Header entfernen/löschen. Dieses einfach in einer Schleife laufen lassen (also von hier wieder zurück zu [1>]) bis der Puffer entweder zu klein für ein Header Packet ist oder der Puffer zu klein ist für ein Header und die im Header angegebenen Folgedaten.

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 13.11.05 22:58 
Moin!

Ich möchte hier nochmal was klarstellen, das IMHO nicht so gut rüber gekommen ist:

Solange es sich um eine TCP-Verbindung handelt (TServerSocket und TClientSocket bauen darauf auf), bleibt die Reihenfolge, in der du Daten sendest, garantiert erhalten oder es gibt eine Exception. Es kann also gar nicht vorkommen, dass du "Buchstabensalat" empfängst, du wirst lediglich Probleme haben (so vermute ich), das gleichzeitige Benutzen von Streams mit SendText zu koordinieren. :wink:

Und da gebe ich meinem Vorredner natürlich uneingeschränkt Recht, das kann man mit einem Protokoll in den Griff kriegen.

cu
Narses
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 14.11.05 12:03 
Also ich hab schon mal von Records oder Buffern gehört, hab aber keinen Dunst wie ihr das meint. Könnt ihr mir mal einen kleinen 'Quelltext-Denkansatz' geben?

@ Narses: Wenn ich dein Posting richtig verstanden habe, dann muss ich dir antworten dass das nicht stimmt. Der CLientsocket schreibt den empfangene text bei mir in ne listbox, ich kann mal einen Screenshot hochladen wenn ihr mir nicht glaubt. Also die Syntax lautet 'getmouse#750#100' und 'click#left' wobei die beiden zahlen für die mauskoordinaten stehen. Also da kommt dann zum beispiel 'getmouse#750#100click#' und danach '#left' an und es passiert halt nix. Ich müsste sicherstellen dass die Strings richtig ankommen, aber das löst man ja durch ein eigenes Protkoll. :wink: Also ich wüsste nicht wie ich sowas maacht

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 14.11.05 12:08 
Moin!

Ganze simpel: pack an das Ende jedes SendText ein #13 und werte die empfangenen Strings entsprechend aus (also immer von einem #13 zum nächsten ist ein String, der zu bearbeiten ist).

cu
Narses
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 14.11.05 17:57 
:think: :think: :think: :think: :think: :think: :think: :think: :think:

Geniale Idee :D Probier ich gleich mal aus!

Thx to you all. You are the best!

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: Mo 14.11.05 19:10 
user profile iconKoller hat folgendes geschrieben:
Geniale Idee :D Probier ich gleich mal aus!


Das das dann schon eine einfachste Form von einem Protokoll ist sage ich dir dann hier mal - es muss ja nicht kompliziert sein, aber ein Protokoll ist es.

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 14.11.05 20:02 
Eine frage noch: Das löst aber irgendwie das Problem nicht. Also was wenn da ankommt: 'click#13' Das wird so passieren. mit Sicherheit. Also wenn ich mir das alles durchdenke dann funktioniert das trotzdem nicht.

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: Mo 14.11.05 20:24 
Narses meinte ja auch nicht #13 als Zeichenkette anzuhängen sondern das Zeichen mit dem ASCII Code 13 - also mit anderen Worten Chr(13) - bzw. wenn du es im Quellcode am String anhängen willst kannst du es auch mit #13 schreiben.

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 14.11.05 20:56 
Und wie könnte man so etwas versenden?

Etwa: clientsocket1.socket.sendtext('click#left'+#13);

oder was?

Und wie muss ich das bei onclientread auswerten?
Das mag ja funktionieren aber ich kann das nicht praktisch umsetzen :gruebel:

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: Mo 14.11.05 21:37 
user profile iconKoller hat folgendes geschrieben:
Und wie könnte man so etwas versenden?

Etwa: clientsocket1.socket.sendtext('click#left'+#13);

oder was?


100 Punkte - genau richtig.

user profile iconKoller hat folgendes geschrieben:
Und wie muss ich das bei onclientread auswerten?
Das mag ja funktionieren aber ich kann das nicht praktisch umsetzen :gruebel:


Klar, ein wenig Stringmanipulation. Schau dir mal die Funktionen Pos(), Copy() und Delete() an.

_________________
49 63 68 68 61 62 65 6B 65 69 6E 65 41 68 6E 75 6E 67 21
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 15.11.05 01:45 
Moin!

Entscheidender Ansatz: mach einen globalen String Command oder so auf, in dem du die ankommenden Strings immer hinten anhängst. Nach jedem Anhängen dann einmal schauen, ob schon (von vorne gesehen) ein "komplettes" Kommando (von #13 umschlossen) angekommen ist. Wenn ja, den Teil vorne abtrennen und verarbeiten. Fertig. :wink:

Hier ist ein Tutorial, dass ausführlich beschreibt, wie man ein Protokoll entwickelt; damit sollten sich die genannten Probleme elegant beseitigen lassen. ;)

Und um nochmal auf den record-Ansatz zurück zu kommen: hier steht, warum das nicht so schlau ist. ;)

cu
Narses