Seite 3 von 3

Re: WriteFile - ReadFile

Verfasst: 15.12.2014 19:36
von stevie1401
Danke für deine Hilfe, das Prog hängt sich allerdings sofort auf, wenn ich deinen Code verwende. Mit timer und auch ohne.

Re: WriteFile - ReadFile

Verfasst: 15.12.2014 20:19
von helpy
Hallo,

Wie sieht denn der Programmteil aus, der die Procedure aufruft? Verwendest Du irgendwo auch NetworkClientEvent?

Läuft irgendetwas in einem Thread?
Wenn ja, dann die Variable StringFromServer evt. gegen gleichzeitiges Überschreiben/Lesen sperren.

Hier Deine Procedure mit kleinen Änderungen:

Code: Alles auswählen

#ReceiveBufferSize = 8192

Procedure ReadNetData()
	Protected Laenge.l, Temp.s, *MemoryID

	*MemoryID = AllocateMemory(#ReceiveBufferSize)
	If *MemoryID
		Repeat
			Laenge = ReceiveNetworkData(ConnectionID, *MemoryID, Puffergroesse)
			If Laenge > 0
				Temp + PeekS(*MemoryID, Laenge, #PB_Ascii)
			EndIf
		Until Laenge < Puffergroesse
		FreeMemory(*MemoryID)

		If Temp <> ""
			StringFromServer + Temp
		EndIf
	EndIf

EndProcedure
Ansonsten würde zur Fehlersuche auch der Kontext, in dem diese Procedure aufgerufen wird, hilfreich zur Fehlersuche sein.
Andernfalls muss man bei manchen Dingen spekulieren!

Re: WriteFile - ReadFile

Verfasst: 15.12.2014 20:48
von stevie1401
Hm, mit deinem Code scheint es tatsächlich zu funktionieren, helpy, vielen Dank! :allright:

Ich frage mich nur wo der Unterschied zu meinem Code ist....

Code: Alles auswählen

Procedure ReadNetData()
  
  Protected Puffergroesse.l, Laenge.l, Temp.s
  Define *MemoryID 
  Puffergroesse = 8192
  *MemoryID = AllocateMemory(Puffergroesse)
  If *MemoryID
    Repeat
      Laenge = ReceiveNetworkData(ConnectionID, *MemoryID, Puffergroesse)
    
      Temp + PeekS(*MemoryID, Puffergroesse,#PB_Ascii)  ;es muss zwingend #PB_ASCII sein, weil die Daten vom Server im ASCII Format gesendet werden.
                                                        ;sonst bleibt es bei Umlauten hängen.
      
    Until Laenge < Puffergroesse
    FreeMemory(*MemoryID)
  EndIf
  StringFromServer=StringFromServer+temp
  
EndProcedure

 

Ist es das:
If Laenge > 0

endif
und:
If Temp <> ""

endif

Vermutlich werden ansonsten einige chr(10) hinzugefügt - woher die auch immer kommen mögen.

Re: WriteFile - ReadFile

Verfasst: 15.12.2014 21:26
von NicTheQuick
Wie gesagt: Eine sauberes Protokoll schickt vorweg die Länge des Strings. Dann kann der Empfänger auch genau entscheiden, ob alles ankam oder nicht. Der aktuelle Code kann zwar funktionieren, kann aber auch genau so fehleranfällig sein.

Re: WriteFile - ReadFile

Verfasst: 15.12.2014 22:58
von helpy
stevie1401 hat geschrieben:Hm, mit deinem Code scheint es tatsächlich zu funktionieren, helpy, vielen Dank! :allright:

Ich frage mich nur wo der Unterschied zu meinem Code ist....
Wenn Du ein wenig über die Zeile "Temp + PeekS(*MemoryID, Puffergroesse,#PB_Ascii)" nachdenkst, dann könntest Du drauf kommen.

Dein Puffer wird laufend gefüllt! Beispiel:
  1. Es kommen 8192 Bytes an, die mit Peeks ohne Probleme gelsen werdne.
  2. Es kommen die nächsten 8192 Bytes und mit Peeks ohne Probleme gelesen.
  3. Es kommen nur 1000 Bytes an, aber Du liest mit Peeks 8192 Zeichen :-(
    Die 7192 Bytes im Puffer sind aber noch alte Daten vom vorherigen Block, die Du nun auch noch einließt.

Re: WriteFile - ReadFile

Verfasst: 15.12.2014 23:05
von helpy
NicTheQuick hat geschrieben:Wie gesagt: Eine sauberes Protokoll schickt vorweg die Länge des Strings. Dann kann der Empfänger auch genau entscheiden, ob alles ankam oder nicht. Der aktuelle Code kann zwar funktionieren, kann aber auch genau so fehleranfällig sein.
Das ist natürlich das Sicherste!

Ein Datenblock kann aber auch durch <BLOCK> und </BLOCK> eindeutig gekennzeichnet sein. Da würde ich persönlich aber auch auf eine max. möglich Blockgröße beim Empfangen prüfen, ansonsten würde im Fehlerfall der Speicher voll geschrieben ;-).

Re: WriteFile - ReadFile

Verfasst: 16.12.2014 00:25
von stevie1401
Sehr schön erklärt, helpy, das habe ich verstanden :-)

Ich würde liebend gerne immer erst dem Client sagen dass Daten in einer Grösse von X gleich ankommen, nur wüsste ich nicht wie ich das anstellen soll.
Viele Dinge ergeben sich während eines Spieles, sodass manchmal auch Strings (Informationen) zusammengelegt werden und dann abgeschickt werden.
Ich kann also NICHT schreiben, es kommen gleich 10 KB Karteninfo an, wenn es zufällig auch noch andere Infos gibt, die eine andere Procedure gerade verarbeitet und diese an den SendString anhängen. Dann wäre die Datenlängeninfo schon falsch, da ich ja abgeschickt habe, es kommen 10 KB Kartendaten an.
Versteht ihr, was ich meine?
Das <Block>String</Block> hat sich bewährt. Stringüberläufe habe ich noch nie erlebt, da der StringFromServer immer um die Info geschnitten wird, die bearbeitet wurde,
<Block>String</Block> wird aus StringfromServer herausgeschnitten, wenn er verarbeitet wird.

Gleichwohl sehe ich ein, dass es erheblich zuverlässiger wäre, wenn man dem Client sagen könnte, was er gleich bekommt.
Aber ich kanns halt leider nicht, bin ja schliesslich kein Profi :-)

Vielen Dank für eure Hilfe :allright:

Re: WriteFile - ReadFile

Verfasst: 16.12.2014 00:33
von helpy
stevie1401 hat geschrieben:Hm, mit deinem Code scheint es tatsächlich zu funktionieren, helpy, vielen Dank! :allright:

Ich frage mich nur wo der Unterschied zu meinem Code ist....
...

If Temp <> ""

endif
OK! Diese Abfrage ist wohl wirklich um sonst ;-) ...