it-swarm.com.de

So prüfen Sie die verfügbaren Datenmengen für einen Socket in C und Linux

Ich habe einen Server, der einen kontinuierlichen Datenstrom empfängt. Im Gegensatz zum mehrfachen Lesen aus einem Socket möchte ich die gesamten Daten im Socket-Empfangspuffer mit einem Systemaufruf an read() lesen.

Natürlich kann ich einen großen Puffer übergeben und read() wird versuchen, ihn mit allen verfügbaren Daten zu füllen. Dies würde jedoch eine Menge Speicherplatz verschwenden, da der malloc-Puffer meistens größer wäre als die auf Socket verfügbaren Daten. Gibt es eine Möglichkeit, die verfügbaren Daten auf einem Socket abzufragen?

28
Jimm

Ja:

#include <sys/ioctl.h>

...

int count;
ioctl(fd, FIONREAD, &count);
50
fizzer

Nein, da ist kein. Selbst wenn es einen Weg dafür gäbe, wäre jede Antwort sofort veraltet (da neue Daten jederzeit ankommen können).

Wenn Sie einen Puffer an read() übergeben, wird die Funktion zurückgegeben, wenn any zu lesende Datenmenge vorhanden ist (mindestens ein Byte), anstatt darauf zu warten, dass der Puffer vollständig gefüllt ist.

4
Greg Hewgill

Dies ist eine "Art" Antwort: recv(char* buffer, size_t nytes, int flags), bei der Flags OR mit:

MSG_PEEK
This flag causes the receive operation to return data from the beginning of the receive queue without removing that data from the queue. Thus, a subsequent receive call will return the same data.

So können Sie sehen, ob eine beliebige Anzahl von Bytes im Puffer vorhanden ist, ohne den Puffer irreversibel zu lesen. Dies ist eine halbe Antwort, da dies nicht die effizienteste Methode ist, und MSG_PEEK wird normalerweise verwendet, wenn Nachrichten mit bekanntem Längenkopf versehen sind.

000123DT001    

dabei ist 00123 die Länge der gesamten Nachricht einschließlich des Headers, DT der Nachrichtentyp und 001 die Anzahl der Wiederholungsversuche des Absenders. Die Idee ist, dass Sie etwas abrufen können, aus dem hervorgeht, wie viele Bytes eine Nachricht vollständig lesen. Sie sind nicht an Nachrichten interessiert. Aber das ist der Grund hinter MSG_PEEK

2
jim mcnamara

Sie müssen das Senden und Empfangen von Befehlen versuchen, und Sie können Socketzeichen für Zeichen lesen und schreiben, um Speicherplatz zu sparen und die Kommunikation zu verbessern.

2
ravi bhuva

Sie können Nicht blockierende Sockets oder select ()/poll () für diese Angelegenheit verwenden. Ich bevorzuge nicht blockierende Sockets, weil ich andere Dinge tun kann, während ich auf neue Daten warte.

1
yeyo

ich denke, Sie versuchen, viele Pakete mit einem einzigen Systemaufruf zu bekommen, um den Overhead aufgrund von Systemaufrufen zu reduzieren.

so können Sie versuchen PACKET Sockets Interfaces für Linux 2.4 oder 2.6+ Kernel versuchen Sie dies http://lxr.free-electrons.com/ source/Documentation/networking/packet_mmap.txt

0
akp