UDP empfangen bis keine Daten mehr kommen

Greenleon

Greenleon

Tripel-As
Hi,

ich bastle im Moment an einem Tool, dass sich Daten von einem UDP Server holen soll.
Dazu stelle ich erst eine Verbindung her, sende dann ein Kommando und will dann so lange empfangen, bis nichts mehr kommt.

Das senden funktioniert gut und ich bekomme auch eine Antwort.

Das Problem ist, dass ich vorher nicht weiss, wie lang die Kette ist, die ich bekomm, deswegen muss ich theoretisch mit while arbeiten.

Der entsprechende Teil sieht so aus, wobei buffer ein char array ist und sock der udp socket.

Code:
 do{
    n=recv(
     sock,
     buffer,
     sizeof(buffer),
     0
    );
   printf("%i\n",n);
   for(i=0; i<sizeof(buffer);i++)
     printf("%c\n",buffer[i]);
   
   } while(n>0);

Auch merkwuerdig ist, dass er die Daten nur ausgibt, wenn ich das \n in printf belasse. Ansonsten gehts nur bis zum ersten Zeilenumbruch in den empfangenen Daten.

Hat jemand ne Idee, wie ich eine gescheite Abbruchbedingung formuliert bekomme und warum die Ausgabe nicht richtig funktioniert?

Danke euch!
 
Hi,

ich bin nicht so der C Crack, und auch mit UDP habe ich noch nie gearbeitet, aber gewisse Vermutungen und Ideen haette ich trotzdem anzubieten. ;)

Dazu stelle ich erst eine Verbindung her, sende dann ein Kommando und will dann so lange empfangen, bis nichts mehr kommt.
IMHO ist das genau genommen schon eine falsche Aussage, denn UDP arbeitet ohne Verbindungen, du schickst einfach drauf los. Es sei denn meine geringen UDP Kenntnisse lassen mich grade voellig im Stich. ;)
UDP kennt zwar Source Port und Destination Port, aber keine Verbindungen.

Das Problem ist, dass ich vorher nicht weiss, wie lang die Kette ist, die ich bekomm, deswegen muss ich theoretisch mit while arbeiten.
[...]
Hat jemand ne Idee, wie ich eine gescheite Abbruchbedingung formuliert bekomme und warum die Ausgabe nicht richtig funktioniert?
Zur Ausgabe siehe weiter unten, aber ich verstehe vor allem nicht warum du nicht einfach TCP benutzt. Aber auch mit UDP lassen sich natuerlich Dinge basteln; ich wuerde wahrscheinlich direkt am Anfang durchgeben lassen wie viele Bytes gesendet werden sollen, und mir das erst ordentlich bestaetigen lassen, bevor die eigentlichen Daten gesendet werden. Das dumme an UDP ist natuerlich, wenn alles ankommen soll, muss auch alles per Hand gecheckt werden. Fuer die genaue Implementierung empfehle ich ein gutes Netzwerkbuch a la Computer Networks von A. Tanenbaum.

Wenn es doch nicht so wichtig ist dass wirklich alles ankommt, koenntest du doch z.B. einfach eine bestimmte Byte oder Bit Reihenfolge als Anfangsmarkierung und eine andere Folge als Endmarkierung mitgeben (jo, wuerde wohl byte oder bit stuffing erfordern). Aber den Anfang und das Ende muesste man sich wohl extra bestaetigen lassen, bestimmte TCP features muessen eben fuer kritische Stellen im Protokoll nachgebaut werden.

Auch merkwuerdig ist, dass er die Daten nur ausgibt, wenn ich das \n in printf belasse. Ansonsten gehts nur bis zum ersten Zeilenumbruch in den empfangenen Daten.
Wie gesagt, meine C Kenntnisse sind eher bescheiden, aber ich wuerde vermuten dass der Rest noch gebuffert ist, und deswegen noch nicht geschrieben wird:
http://drpaulcarter.com/cs/common-c-errors.php#4.3

Statt \n mal fflush(stdout) probiert?

mfg,
bytepool
 
Technisch gesehen hast du Recht. UDP ist Verbindungslos.
Aber connect() in C kann man trotzdem aufrufen dann muss man beim Empfangen und Senden weniger Argumente uebergeben.

Ich hab jetzt aber schon eine Loesung gefunden.
Ich ueberpruefe, ob weniger Bytes empfangen wurden als die Puffergroesse ist, wenn ja, dann nehme ich einfach das Ende der Uebertragung an.

Ich teste das mal ausgiebig.

Ich benutze UDP, da die Serverapplikation nicht von mir ist. Ich versuche mir die Serverliste von nem Masterserver zu holen.
 
Falls die Daten nur sporadisch kommen, könnte man auch in einem
subthread nen Timer laufen lassen und bei Zeitüberschreitung nen
Schalter im While abfragen. Dazu müßte man dann allerdings non-blocking lesen und
auch hier ne kurze Wartezeit einbauen (wegen CPU-Last).
 
Hab rausgefunden, dass der Server immer EOF am Ende des letzten Pakets sendet. Ueberpruefe jetzt einfach bei jedem Schleifendurchlauf ob die letzten 3 Bytes ASCII 'E' 'O' 'F' entsprechen und breche dementsprechend ab.

Aber danke :-)
 

Ähnliche Themen

Unix Webserver mit HTML Seite erstellen

Server und Client für TCP und UDP

"send: Cannot determine peer address" nach Timeout mit UDP Server -Perl Socket eval{}

C HTTP request

iptables - default policy - Server macht dicht

Zurück
Oben