länge eines UDP-Paketes herrausfinden
-
Hallo
der titel sagt es schon, wie kann man die größe eines angekommenen paketes
herrausfinden ?wenn ich die daten einfach nur empfange fliegt alles was nicht beim ersten
mal kopiert wurde, raus. deshalb brauche ich die länge.
-
z.B.
result = recvfrom(socket, buffer, sizeof(buffer), 0, NULL, NULL);wobei result die Anzahl der empfangenen Zeichen beträgt. Musst halt mal in der MSDN lesen
-
das ist mir durchaus bekannt, dass die funktion mir die länge gibt.
allerdings nur maximal die bufferlänge. wenn mein buffer 256 bytes groß ist,
die nachricht aber z.b. 1024 bytes, wie komme ich an die gesammtlänge?klar ich könnte die bei jedem packet mit schicken aber
dann müsste die send funktion alles wegen 4 bytes (sollte als größe reichen)
umkopieren
nicht schön
oder ich schicke die länge vorneweg. UDP garantiert aber keine reihenfole
mal ist die länge weg, mal das paket, mal überholen die sich...es muss doch gehen, im UDP header steht doch auch die länge
hoffe man hat mein problem verstanden
mfg UhDehPeh
-
Du hasts wohl echt nicht so mit Lesen, was?
MSDN schrieb:
For message-oriented sockets, data is extracted from the first enqueued message, up to the size of the buffer specified. If the datagram or message is larger than the buffer specified, the buffer is filled with the first part of the datagram, and recvfrom generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost.
Kurz: wenn du einen zu kleinen Puffer übergibst ist die Nachricht sowieso schon futsch, und du bekommst die Original-Länge auch nichtmehr raus.
Also übergib einfach nen ausreichend grossen Puffer!?!
-
doch ich lese
sogar die remarks abteilung (echt) und da stehtFor unreliable protocols (for example, UDP) the excess data is lost.
geht garnicht, ich kann die nachricht nicht einfach abschneiden
Also übergib einfach nen ausreichend grossen Puffer!?!
super, jeder socket hat MAX_UDP_SIZE (65kb) overhead juhu

nein auch in der heutigen zeit passe ich auf den speicher aufwas ich grade herausgefunden habe ist, dass man mit MSG_PEEK den ersten teil
einlesen kann, wo dann die größe drinsteht (so implementiert)
und dann für diese menge speicher anfordertideal ist das aber immernoch
ps:
ich kenne diese msdn-seite bald auswendig!
-
Also.
Wenn du blocking sockets verwendest hast du sowieso kein Problem, dann nimmst du die 64KB einfach vom Stack und fertig.Wenn du nonblocking sockets mit select() verwendest genauso.
Wenn du overlapped IO verwendest... pfuh. Allerdings entzieht sich mir jetzt sowieso gerade wieso man bei UDP viele sockets brauchen sollte - schliesslich kann ich ja einen socket verwenden um mit allen meinen Peers zu sprechen. Und wenn man bloss einen oder ein paar wenige sockets hat, dann kann man sich die 64KB wohl leisten.
Falls das alles jetzt irgendwie nicht auf dein Problem anwendbar ist beschreib mal bitte wieso, bzw. was du für spezielle Anforderungen hast, vielleicht kann dir dann jmd. einen Tip geben. Die "Lösung" MSG_PEEK + Länge im Datagram mitschicken halte ich auf jeden Fall für nicht sehr elegant.
Davon abgesehen kennt man normalerweise die max. Grösse eines (gültigen) Datagrams anhand des Application-Protocols das man implementiert, und die liegt dann oft weit unter 64KB. Demzufolge braucht man dann auch keine 64KB Puffer, da ein Datagram das grösser als X ist eben nicht gültig sein kann,und man es daher sowieso verwerfen wird.
-
erstmal danke an alle die sich mit meinem problem beschäftigen!
ok also der ganze hintergrund
ich habe mir eine kleine netzwerklibrary geschrieben um unkompliziert
und vor allen objektorientiert daten leicht von A nach B zu versendenNatürlich sind die sockets auch gekapselt d.h. ich habe dafür die
entsprechenden methodenTCP funktioniert auch super, nur hat TCP protokollbedingt eine zu
hohe latenzzeit als das man damit schnelle netzwerkspiele schreiben könntedeshalb sollen die sockets auch UDP unterstützen, und zwar blocking
da alle sockets eines prozesses von einer netwerkklasse verwaltet
werden, könnte ich den buffer einmal anlegen. dann hätte ich den zusätzlichen
speicher nur einmal.die datenmengen werden sich sowieso unter 64kb bewegen, für große mengen
nimmt die klasse dann TCPich teste mal den stackbuffer
hustbaer:
warum ist diese 'Lösung' mit MSG_PEEK nicht elegant?
um die vergrößerung um 4 Bytes konnte ich mich auch geschickt drücken,
daran scheitet es also nichtmfg UhdefPeh
-
warum ist diese 'Lösung' mit MSG_PEEK nicht elegant?
um die vergrößerung um 4 Bytes konnte ich mich auch geschickt drücken,
daran scheitet es also nichtweil du mit MSG_PEEK zwei aufrufe brauchst wo sonst einer reicht.
ich fände es einfach "hässlich".vor allem da die variante mit stack buffer viel einfacher, übersichtlicher, kürzer etc. ist.
char buffer[1024*64]; int rc = recvfrom(...);und 64KB auf dem stack sind nix wovor man sich jetzt fürchten müsste. vorausgesetzt die funktion ist nicht rekursiv, und das programm läuft auf einer plattform die mächtiger ist als eine armbanduhr.