Wie verhält sich ein UDP-Stream?

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Rick_72

Betreff: Wie verhält sich ein UDP-Stream?

BeitragDi, Sep 29, 2009 18:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo mal wieder!

Was passiert eigentlich mit einem UDP-Stream, der mehrere Msg. empfängt? Werden diese einfach aneinander gehängt (also an den Stream)?

Wenn ich eine empfangene Msg. lese, wird diese dann aus dem Stream gelöscht oder wächst dieser (der Stream) ins Unendliche (oder bis zu einem gewissen Max-Wert, um dann wieder von vorne zu starten)?

Was passiert eigentlich, wenn ich während des Lesens einer Msg. eine andere Msg. empfange? Geraten dann die File-Pointer durcheinander?

Könnt ihr mir bei diesen Fragen weiterhelfen?
Danke für Eure Mühen!
 

BIG BUG

BeitragDi, Sep 29, 2009 18:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Die ankommenden Daten werden gepuffert. Du musst jede einzelne Message mit RecvUDPMsg abfragen. Gibt RecvUDPMsg 0 zurück, dann liegt keine Message mehr im Puffer.

Also einfach so:
Code: [AUSKLAPPEN]
   
;read all input messages
While RecvUDPMsg(gStream)
   ;hier die Messages verarbeiten
Wend


Ist eine Message ausgelesen, wird diese aus dem Puffer gelöscht.
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final)

Rick_72

BeitragDi, Sep 29, 2009 19:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:

Ist eine Message ausgelesen, wird diese aus dem Puffer gelöscht.


Das heisst also, die Kiste merkt sich, ob ich mindestens einmal über die komplette Message gelesen habe (was heisst in dem Fall konkret "Message lesen")? Muss ich "jedes Byte" der Msg. mit Read abfragen, und dann wird die Msg. gelöscht? Heisst das im Umkehrschluss, dass bei mehreren Messages im Buffer erst eine komplett gelesen sein muss, damit man Zugriff auf die anderen Messages hat?

Wird der Stream-Pointer dann bei mehreren Messages im Buffer nach FIFO gesetzt?

Tankbuster

BeitragDi, Sep 29, 2009 19:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würd es immer so machen, dann kommt es nicht so leicht zu Datenstau: Wink
Zitat:
If RecvUDPMsg(Stream)
While not Eof(stream)
;hier die Messages verarbeiten
Wend
Endif



Wenn du mehrere Sachen in eine Nachricht packst
(
WriteByte Stream,1
WriteByte Stream,2
WriteByte Stream,3
SendUDPMsg
)

Dann wird das Byte aus dem Puffer gelöscht, sobald es gelesen wurde. Nicht erst, wenn die ganze Nachricht vertig verarbeitet wurde Wink


Zitat:
Heisst das im Umkehrschluss, dass bei mehreren Messages im Buffer erst eine komplett gelesen sein muss, damit man Zugriff auf die anderen Messages hat?

Du kannst mit SeekFile an einen beliebigen Ort im Buffer springen. Allerdings ist das absolut garnicht zu empfehlen, denn ankommende Nachrichten sollten eigentlich immer verarbeitet werden. Sonst hätten sie ja auch keinen Sinn Wink
Twitter
Download Jewel Snake!
Windows|Android

Rick_72

BeitragMi, Sep 30, 2009 10:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Also, falls jemand mal die gleichen Fragen gehabt haben sollte wie ich, hier eine kleine Zusammenfassung:

- eingehende Messages werden nach FIFO vom System zur Verfügung gestellt
- nachdem jedes Byte einmal gelesen wurde (ReadAvail dekrementiert entsprechend), wird EOF gesetzt
- obwohl noch Messages im Stream liegen, kann man auf diese nicht zugreifen (es sei denn evtl. per Seekfile o.ä.), solange man nicht RecvUDPMsg ausführt
- das Auslesen des Streams wird nicht gestört, wenn zeitgleich eine Message ausgelesen wird (habe ich ausprobiert; zumindest im Testfall klappte das)

Ist die Zahl der Messages im Stream nicht bekannt (wann ist das schon der Fall?), so kann man also (siehe BIG BUGs Posting) die Messages im Stream so abarbeiten:

Code: [AUSKLAPPEN]

While RecvUDPMsg(stream)<>0
   While Not Eof(stream)
      Stream (komplett) auslesen   
   Wend
Wend
 

BIG BUG

BeitragMi, Sep 30, 2009 21:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Ich würd es immer so machen, dann kommt es nicht so leicht zu Datenstau: Wink
Zitat:
If RecvUDPMsg(Stream)
While not Eof(stream)
;hier die Messages verarbeiten
Wend
Endif


Auf diese Weise liest Du immer nur eine Message aus dem Puffer ein und es kommt somit leichter zu Datenstau Smile
Erst mit RecvUDPMsg wird die nächste im Puffer vorhandene Message bereitgestellt. Es ist übrigens egal, ob die komplette Message ausgelesen wurde, sobald das nächste mal RecvUDPMsg ausgeführt wird, wird die alte Message gelöscht.
Es ist aber richtig, dass mit EOF geprüft werden kann, ob bereits die komplette Message ausgelesen wurde.

Eine Message entspricht einem Paket, also einmal SendUDPMsg auf der Senderseite.
Es ist übrigens zu beachten, dass ein Paket nicht größer als 8192 Byte werden darf...
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final)

Tankbuster

BeitragMi, Sep 30, 2009 21:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Eine Message entspricht einem Paket, also einmal SendUDPMsg auf der Senderseite.
Es ist übrigens zu beachten, dass ein Paket nicht größer als 8192 Byte werden darf...


Ein Paket sollte nur ~1400 Bytes enthalten. Dann wird immernoch alles in einem Ethernet Paket übertragen. Alles andere ist Unsinn, denn dann kann es viel leichter vorkommen, dass eine Nachricht mal nur zur Hälfte ankommt. Sonst kommt sie entweder an oder nicht an. Wink
Klar kann man UDP Pakete ziemlich groß machen, aber dann werden sie in mehreren Frames übertragen und können sich überhohlen, ect. Darum möglichst wenig versenden, damit alles in ein Ethernet Paket passt.


Meine Möglichkeit ist zwar nicht ganz so ausgereift, aber sobald eine Nachricht empfangen wird, wird der KOMPLETTE Stream ausgelesen. Genau wie bei der andern. Wenn eine Nachricht während des auslesens ankommt wird sie ebenso ausgelesen wie bei Rick_72's Methode. Alles in allem kein wirklicher Unterschied.

Sonst müsste sich bei meinen Projekten ständig Datenstau entwickeln, was aber nicht passiert, obwohl mein Verwaltungsserver nur mit 1 FPS läuft Wink
Twitter
Download Jewel Snake!
Windows|Android
 

BIG BUG

BeitragMi, Sep 30, 2009 22:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielleicht meinst Du es ja anders, aber so kommt bei mir nur eine Nachricht an:

Empfänger, zuerst starten, nachdem Sender durchgelaufen ist Taste drücken:
Code: [AUSKLAPPEN]

stream = CreateUDPStream(8000)

WaitKey()

Print "Begin of Message"
If RecvUDPMsg(Stream)
   While Not Eof(stream)
      Print ReadString(stream)
   Wend
EndIf
Print "End of Message"

WaitKey()


Sender, durchlaufen lassen nachdem Empfänger gestartet wurde
Code: [AUSKLAPPEN]

CountHostIPs("127.0.0.1")

stream = CreateUDPStream(8001)

WriteString stream, "Message 1"
SendUDPMsg stream, HostIP(1), 8000

WriteString stream, "Message 2"
SendUDPMsg stream, HostIP(1), 8000
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final)

Rick_72

BeitragDo, Okt 01, 2009 12:09
Antworten mit Zitat
Benutzer-Profile anzeigen
[quote="BIG BUG"]Zitat:
Erst mit RecvUDPMsg wird die nächste im Puffer vorhandene Message bereitgestellt. Es ist übrigens egal, ob die komplette Message ausgelesen wurde, sobald das nächste mal RecvUDPMsg ausgeführt wird, wird die alte Message gelöscht.


Das ist noch ein sehr wichtiger Punkt, Danke BIG BUG! Vielleicht sollte man all diese Punkte mal als Ergänzung hier ins Manual zu dem UDP-Kram stellen. Das wird sicherlich noch ein andere interessieren.


Gibt es eigentlich eine Möglichkeit die Anzahl der wartenden Pakete zu ermitteln, ohne sie auszulesen (resp. im Datenhimmel zu versenken)?

Starwar

BeitragDo, Okt 01, 2009 14:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Nein die gibts nur bei TCP (ReadAvail).
Du kannst aber alle Pakete auslesen und in einem Type zwischenspeichern. Dann kennst du auch immer die Anzahl.
MFG

Tankbuster

BeitragDo, Okt 01, 2009 14:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh, ich muss mich entshculdigen. Ich hatte wohl doch Unrecht. Komisch, denn ich hab schon soviel mit dem Zeugs gemacht, aber es ist mir nie aufgefallen. Die Lösung mit dem "While RecvUDPMsg" ist wohl wirklich die beste.
Cool, endlich nochmal was dazugelernt Smile
Twitter
Download Jewel Snake!
Windows|Android

Rick_72

BeitragDo, Okt 01, 2009 14:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Starwar hat Folgendes geschrieben:
Nein die gibts nur bei TCP (ReadAvail).
Du kannst aber alle Pakete auslesen und in einem Type zwischenspeichern. Dann kennst du auch immer die Anzahl.
MFG


ReadAvail ermittelt die Zahl der aus dem Stream auslesbaren Bytes. Das ist nicht auf TCP beschränkt. Aber mir ging's ja im wesentlichen auch nur darum, die Zahl der wartenden Pakete zerstörungsfrei zu ermitteln. Das geht wohl nur mit der von Dir vorgeschlagenen Methode: alles auslesen, zählen und zwischenspeichern.

Starwar

BeitragDo, Okt 01, 2009 14:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich bin davon ausgegangen es funktioniert nicht, weil UDP nicht in der Parameterliste von ReadAvail aufgelistet ist. Ich habe es bei UDP nie verwendet.
MFG

Rick_72

BeitragDo, Okt 01, 2009 14:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Eben nochmal probiert: scheint zu klappen. Der Stream-Typ scheint keine Rolle zu spielen.

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group