AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Ist der Server zu "schnell"?
Thema durchsuchen
Ansicht
Themen-Optionen

Ist der Server zu "schnell"?

Ein Thema von NightroadSora · begonnen am 28. Mär 2011 · letzter Beitrag vom 30. Mär 2011
Antwort Antwort
Benutzerbild von wicht
wicht

Registriert seit: 15. Jan 2006
Ort: Das schöne Enger nahe Bielefeld
809 Beiträge
 
Delphi XE Professional
 
#1

AW: Ist der Server zu "schnell"?

  Alt 29. Mär 2011, 00:03
Woher hast du das Beispiel da oben denn? Ich würde jedenfalls sagen, dass das nur in den seltensten Fällen so funktionieren kann. Versuch es doch mal nach folgendem Schema...

Client:
Code:
procedure SendeDaten;
var
  Rec: TInfo;
begin
  Rec.Zahl := 123;
  Rec.Zahl2 := 456;
  Client.SendBuf(Rec, SizeOf(Rec));
end;
Server:
Code:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Info: TInfo;
begin
  if Socket.Peek >= SizeOf(Info) then
    Socket.ReadBuf(Info, SizeOf(Info));
end;
Du musst eben immer prüfen, ob schon alle Daten da sind, die du einlesen möchtest (hier mit der Methode Peek(), die es vermutlich so nicht gibt an deiner Klasse). Einfach in einen Record lesen, obwohl keine Daten da sind, geht dann schief, und deine Exception "'' ist kein gültiger Integerwert" deutet darauf hin, dass ReceiveText() keine Daten bekommt und StrToInt() daneben geht. Achja, ausserdem dürfen keine normalen Strings in dem Record enthalten sein, wenn man ihn so verschickt/empfängt.
Wenn du flexibel sein möchtest, solltest du das Protokoll vielleicht auch etwas ändern. Man könnte vielleicht Kommandolänge+Kommandotyp+Nutzdaten nehmen, also schickt der Client zwei Integers und dann die Nutzdaten, der Server wartet mit dem Auslesen, bis er die Mindestlänge empfangen hat (den ersten Integer für die Länge). Wenn dieser da ist, weiß der Server, auf wieviele Bytes er noch warten muss. Ist dann alles da, kann man das Paket auseinandernehmen und verarbeiten.
http://streamwriter.org

"I make hits. Not the public. I tell the DJ’s what to play. Understand?"
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Ist der Server zu "schnell"?

  Alt 29. Mär 2011, 06:37
Wie ich bereits erwähnte, wird OnClientRead aufgerufen, wenn Daten da sind. Das heißt aber nicht, dass das erst passiert, wenn ALLE Daten da sind. So ein Socket ist wie ein Schlauch, durch den Kugeln rollen. Du kippst vorne welche rein und irgendwann trudeln die hinten wieder raus. Aber ob die am Stück herauskommen, oder peu-a-peu, das weiss man nicht. Das einzige, worauf Du dich (eigentlich) verlassen kannst, ist die Reihenfolge der Kugeln und das alle ankommen (meistens). Wenn aber jemand den Schlauch durchschneidet, haste Pech.

Du musst Dir selbst Gedanken machen, wie Du sicherstellst, das alle Daten angekommen sind. Dazu kannst Du auf die erste Kugel schreiben, wie viele denn nun kommen. Oder Du färbst die letzte Kugel ROT. Dann dürfen aber in den Nachrichten keine rote Kugeln vorkommen. Oder Du überklebst rote Kugeln mit einem großen Schild: "ROTE Kugel" und färbst die im Client wieder ein, nachdem die ENDE-Kugel (die ja auch rot ist) angekommen ist.

Egal wie, Du musst die Daten also erst einmal sammeln.

So zum Beispiel (Pseudocode, aber vielleicht verständlich):
Delphi-Quellcode:
...
MyBuffer.AddBytes (BytesFromSocket);
While True Do
  If TotalLength = 0 then
    If MyBuffer.Count >= 4 then begin // 4-Byte Längeninfo ist angekommen
      TotalLength := MyBuffer.FirstFourBytesAsInteger; // Die 4 Bytes als Integer interpretieren
      MyBuffer.RemoveBytes (4); // und dann vorne wegschnippeln
    end else
      break // Die Längeninformation ist noch nicht vollständig
  else
    If MyBuffer.Count >= TotalLength then begin // Alle Bytes sind angekommen
// (es könnte aber auch schon ein Teil des nächsten Blocks dabei sein)
      Data := MyBuffer.ExtractBytes (TotalLength); // Datenblock extrahieren
      MyBuffer.RemoveBytes(TotalLength); // wegschnippeln
      ProcessData (Data); // verarbeiten (sollte schnell gehen)
      TotalLength := 0; // und auf den nächsten Block warten
  End else
    break; // Die Dateninformation ist noch nicht vollständig
Die Schleife dient dazu, sofort alle vollständig empfangenen Blöcke zu verarbeiten.

Alternativ kannst Du auch mit einem speziellen Endezeichen (rote Kugel) arbeiten:
Delphi-Quellcode:
...
MyBuffer.Add (BytesFromSocket);
EndPos := MyBuffer.PositionOf (EndOfDataMarker);
While EndPos >= 0 Do Begin
  Data := MyBuffer.ExtractBytes (EndPos); // Datenblock extrahieren
  MyBuffer.RemoveBytes(EndPos+1); // Datenblock + Endmarker wegschnippeln
  ProcessData (Data); // verarbeiten (sollte schnell gehen)
  EndPos := MyBuffer.PositionOf (EndOfDataMarker);
End;
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
NightroadSora

Registriert seit: 27. Mär 2011
11 Beiträge
 
#3

AW: Ist der Server zu "schnell"?

  Alt 29. Mär 2011, 16:41
OKay die Idee an sich dahinter hab ich jetzt immerhin schonmal verstanden. Aber wie krieg ichn jetzt explizit bei nem TServerSocket raus, wie viel er schon empfangen hat?

alzaimar arbeitet ja mit ner Variable namens mybuffer, von welchem Typ soll die denn sein? Ich kenne die methoden addbytes, extractbytes usw nämlich gar nich...
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#4

AW: Ist der Server zu "schnell"?

  Alt 29. Mär 2011, 16:46
Das ist pseudocode. Aber wenn Du noch gar nicht richtig programmieren kannst, sind Sockets eh nix für dich.

Versuch dich an den Indy-Komponenten, das sollte einfacher für dich sein.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
NightroadSora

Registriert seit: 27. Mär 2011
11 Beiträge
 
#5

AW: Ist der Server zu "schnell"?

  Alt 29. Mär 2011, 16:55
Programmieren kann ich schon, nur dachte ich trotzdem dass du mit Klassenobjekten arbeiten, von denen mit die Methoden einfach nur unbekannt sind mehr nich...

Die Indykomponenten lad ich mir tatsächlich grade runter, in der Hoffnung dass die besser funktionieren so wie ichs mir vorstelle...
  Mit Zitat antworten Zitat
NightroadSora

Registriert seit: 27. Mär 2011
11 Beiträge
 
#6

AW: Ist der Server zu "schnell"?

  Alt 29. Mär 2011, 22:10
Also mit den INdykomponenten funktioniert bei mir gar nichts...

also nochmal:
Ich muss jetzt auslesen a) Wie groß wird die gesendete Information sein die an den Server geschickt wird
b) wie groß ist der Datensatz den Server bereits empfangen hat!

So... ich möchte jetzt gern erlernen wie das bei einem TServerSocket funktionieren würde, im INternet finde ich einfach keine vollständige Methoden und Eigenschaftenübersicht...

Zumal ServerSocket.Socket hat ja die Methode recievelength, aber wieso gibts für Client/Server.Socket keinen Sendlength? Is doch völlig bescheuert... und wenn ich jetzt SizeOf(Info) bei nem recieve(Info,SizeOf(Info)) verarbeiten will, is das immer irgendwie nichts...

Man wie mach ich das denn? Das kann doch nich so schwierig sein...
Ich verstehe einfach nich wie ich den Buffer des servers auslesen soll!
  Mit Zitat antworten Zitat
Benutzerbild von wicht
wicht

Registriert seit: 15. Jan 2006
Ort: Das schöne Enger nahe Bielefeld
809 Beiträge
 
Delphi XE Professional
 
#7

AW: Ist der Server zu "schnell"?

  Alt 29. Mär 2011, 22:20
Zitat:
Ich muss jetzt auslesen
a) Wie groß wird die gesendete Information sein die an den Server geschickt wird
b) wie groß ist der Datensatz den Server bereits empfangen hat!
a) ist über. Warum muss der Client das wissen? Der schickt einfach ganz stumpf die Daten. Wenn er was wissen muss, ließt er einfach die Daten, die vom Server zurückkommen.
b) siehe hier, falls das die Komponente ist, die du benutzt. Damit weißt du dann, wieviel Daten schon da sind. Und wenn ReceiveLength > SizeOf(Integer) (Länge am Anfang des Pakets) oder ReceiveLength > SizeOf(Record) (Record empfangen), je nach dem Protokoll, das du baust, kannst du die Daten dann auch lesen.


HTH..
http://streamwriter.org

"I make hits. Not the public. I tell the DJ’s what to play. Understand?"
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz