ssize_t recv(int socket, void *buffer, size_t length, int flags);

Die recv()-Funktion wird bei einem Socket verwendet bei dem zuvor die connect()-Funktion aufgerufen wurde. Die Funktion dient dazu, Daten von einem Socket zu empfangen, der durch den Parameter socket angeben wird. Die Anzahl der Zeichen, die empfangen werden sollen werden durch den Parameter length angegeben. Der Parameter flags spezifiziert besondere Merkmale, die beim Datenempfang berücksichtigt werden sollen. In der Regel erhalten sie den Wert 0. Sollte ein Fehler aufgetreten sein, liefert die Funktion den Wert -1.

Beim Empfang ist zwischen zwei Fällen zu unterscheiden: Der Socket ist blockierend, d.h. der aufrufende Prozess wird vertagt bis Daten zum Empfang bereitstehen oder der Socket ist nicht blockierend: Bei einem nicht blockierenden Socket wird nachgeschaut, ob Daten zum Empfang bereit stehen. Wenn nicht, dann wird die Funktion sofort beendet. Ob Daten bereitstehen kann mit der select()-Funktion überprüft werden.

In jedem Fall, ob blockierend oder nicht, liefert die Funktion als Rückgabewert die Anzahl der empfangenen Zeichen, die sich im Puffer (Parameterbuffer) befinden.

Bei der Handhabung der recv()-Funktion ist Vorsicht geboten, da in bestimmten Fällen Datenverlust auftreten kann: Wenn ein Server Daten versendet und anschließend den Socket schließt, dann kann es passieren, dass der Empfänger die Daten nicht konsumiert hat. Z.B. hat der Empfänger gerade keine Zeit die Daten zu lesen. In diese Fall ist der Socket bereits geschlossen, ohne dass die Daten gelesen wurden. Um einen solchen Fall zu verhindern, sollte in einem Master/Slave Betrieb nur der Master eine Kommunikation beenden und nicht der Slave. D.h. erst wenn der Slave alle angeforderten Daten gesendet hat, dann wird vom Master der Socket geschlossen.

Des weiteren ist zu beachten, dass in Kommunikationssystemen Daten in logischen Einheiten mit unterschiedlicher Länge (sogenannte Rahmen) zusammengefasst werden. Die Socket-Schnittstelle stellt nicht sicher, dass komplette Rahmen empfangen werden. Um sicherzustellen, dass aus Datenfragmenten wieder komplette Rahmen werden, gibt es viele Möglichkeiten. Die einfachste Möglichkeit ist es die Rahmenlänge konstant zu halten. In diesem Fall kann durch einen einfachen Zähler der Rahmenbeginn erkannt werden. Die recv()-Funktion kann durch die read()-Datei-Funktion ersetzt werden, da - wie erwähnt - ein Socket wie ein Datei-Deskriptor behandelt wird. Deshalb sind Dateifunktionen auch auf Sockets anwendbar.

Beispiel:

int sock;
char buffer[10];

int read_bytes = recv(sock, buffer, 10, 0);
if(read_bytes < 0)
{
	perror(“recv stream socket”);
	exit(1);
}