recv-Funktion (winsock.h)

Die recv-Funktion empfängt Daten von einem verbundenen Socket oder einem gebundenen verbindungslosen Socket.

Syntax

int recv(
  [in]  SOCKET s,
  [out] char   *buf,
  [in]  int    len,
  [in]  int    flags
);

Parameter

[in] s

Der Deskriptor, der einen verbundenen Socket identifiziert.

[out] buf

Ein Zeiger auf den Puffer zum Empfangen der eingehenden Daten.

[in] len

Die Länge des Puffers in Bytes, auf den der buf-Parameter verweist.

[in] flags

Ein Satz von Flags, die das Verhalten dieser Funktion beeinflussen. Weitere Informationen finden Sie weiter unten im Abschnitt "Hinweise". Ausführliche Informationen zum möglichen Wert für diesen Parameter finden Sie im Abschnitt Hinweise.

Rückgabewert

Wenn kein Fehler auftritt, gibt recv die Anzahl der empfangenen Bytes zurück, und der Puffer, auf den der buf-Parameter verweist, enthält diese empfangenen Daten. Wenn die Verbindung ordnungsgemäß geschlossen wurde, ist der Rückgabewert null.

Andernfalls wird der Wert SOCKET_ERROR zurückgegeben, und ein bestimmter Fehlercode kann durch Aufrufen von WSAGetLastError abgerufen werden.

Fehlercode Bedeutung
WSANOTINITIALISIERT
Vor der Verwendung dieser Funktion muss ein erfolgreicher WSAStartup-Aufruf erfolgen.
WSAENETDOWN
Fehler beim Netzwerksubsystem.
WSAEFAULT
Der buf-Parameter ist nicht vollständig in einem gültigen Teil des Benutzeradressraums enthalten.
WSAENOTCONN
Der Socket ist nicht verbunden.
WSAEINTR
Der (blockierende) Anruf wurde über WSACancelBlockingCall abgebrochen.
WSAEINPROGRESS
Ein blockierter Windows Sockets 1.1-Aufruf wird ausgeführt, oder der Dienstanbieter verarbeitet noch eine Rückruffunktion.
WSAENETRESET
Bei einem verbindungsorientierten Socket gibt dieser Fehler an, dass die Verbindung aufgrund einer Keep-Alive-Aktivität unterbrochen wurde, die während des Vorgangs einen Fehler erkannt hat. Für einen Datagrammsocket zeigt dieser Fehler an, dass die Gültigkeitsdauer abgelaufen ist.
WSAENOTSOCK
Der Deskriptor ist kein Socket.
WSAEOPNOTSUPP
MSG_OOB angegeben wurde, aber der Socket nicht im Streamstil wie typ SOCK_STREAM, werden OOB-Daten in der diesem Socket zugeordneten Kommunikationsdomäne nicht unterstützt, oder der Socket ist unidirektional und unterstützt nur Sendevorgänge.
WSAESHUTDOWN
Die Steckdose wurde heruntergefahren; Es ist nicht möglich, auf einem Socket zu empfangen, nachdem das Herunterfahren aufgerufen wurde, wobei auf SD_RECEIVE oder SD_BOTH festgelegt ist.
WSAEWOULDBLOCK
Der Socket wird als nicht blockiert markiert, und der Empfangsvorgang würde blockiert.
WSAEMSGSIZE
Die Nachricht war zu groß für den angegebenen Puffer und wurde abgeschnitten.
WSAEINVAL
Der Socket wurde nicht mit bind gebunden, oder es wurde ein unbekanntes Flag angegeben, oder MSG_OOB für einen Socket mit aktiviertem SO_OOBINLINE oder (nur für Bytestreamsockets) angegeben wurde, war len null oder negativ.
WSAECONNABORTED
Timeout- oder anderer Fehler. Die virtuelle Verbindung wurde beendet. Die Anwendung sollte den Socket schließen, weil er nicht mehr verwendbar ist.
WSAETIMEDOUT
Netzwerkfehler oder Antwortfehler des Peersystems. Die Verbindung wurde abgebrochen.
WSAECONNRESET
Die virtuelle Verbindung wurde von der Remoteseite zurückgesetzt, die einen harten oder abbrechenden Schließvorgang ausgeführt hat. Die Anwendung sollte den Socket schließen, weil er nicht mehr verwendbar ist. Bei einem UDP-Datagrammsocket würde dieser Fehler darauf hindeuten, dass ein vorheriger Sendevorgang zu einer ICMP-Meldung "Port unreachable" geführt hat.

Hinweise

Die recv-Funktion wird verwendet, um eingehende Daten auf verbindungsorientierten Sockets oder verbindungslosen Sockets zu lesen. Bei Verwendung eines verbindungsorientierten Protokolls müssen die Sockets verbunden sein, bevor recv aufgerufen wird. Bei Verwendung eines verbindungslosen Protokolls müssen die Sockets gebunden werden, bevor recv aufgerufen wird.

Die lokale Adresse des Sockets muss bekannt sein. Verwenden Sie für Serveranwendungen eine explizite Bindungsfunktion oder eine implizite Accept - oder WSAAccept-Funktion . Von einer expliziten Bindung für Clientanwendungen wird abgeraten. Bei Clientanwendungen kann der Socket implizit mit connect, WSAConnect, sendto, WSASendTo oder WSAJoinLeaf an eine lokale Adresse gebunden werden.

Bei verbundenen oder verbindungslosen Sockets schränkt die recv-Funktion die Adressen ein, von denen empfangene Nachrichten akzeptiert werden. Die Funktion gibt nur Nachrichten von der in der Verbindung angegebenen Remoteadresse zurück. Nachrichten von anderen Adressen werden (automatisch) verworfen.

Für verbindungsorientierte Sockets (z. B. Typ SOCK_STREAM) gibt der Aufruf von recv so viele Daten zurück, wie derzeit verfügbar sind – bis zur Größe des angegebenen Puffers. Wenn der Socket für den Inlineempfang von OOB-Daten konfiguriert wurde (Socketoption SO_OOBINLINE) und OOB-Daten noch ungelesen sind, werden nur OOB-Daten zurückgegeben. Die Anwendung kann den Befehl ioctlsocket oder WSAIoctlSIOCATMARK verwenden, um zu bestimmen, ob weitere OOB-Daten noch gelesen werden müssen.

Für verbindungslose Sockets (Typ SOCK_DGRAM oder andere nachrichtenorientierte Sockets) werden Daten aus dem ersten in die Warteschlange gestellten Datagramm (Nachricht) aus der Zieladresse extrahiert, die von der Verbindungsfunktion angegeben wird.

Wenn das Datagramm oder die Nachricht größer als der angegebene Puffer ist, wird der Puffer mit dem ersten Teil des Datagramms gefüllt, und recv generiert den Fehler WSAEMSGSIZE. Bei unzuverlässigen Protokollen (z. B. UDP) sind die überschüssigen Daten verloren. Für zuverlässige Protokolle werden die Daten vom Dienstanbieter aufbewahrt, bis sie erfolgreich gelesen werden, indem recv mit einem ausreichend großen Puffer aufgerufen wird.

Wenn keine eingehenden Daten am Socket verfügbar sind, blockiert der recv-Aufruf und wartet, bis Daten gemäß den für WSARecv definierten Blockierungsregeln mit dem MSG_PARTIAL Flag nicht festgelegt werden, es sei denn, der Socket ist nicht blockiert. In diesem Fall wird der Wert SOCKET_ERROR zurückgegeben, wobei der Fehlercode auf WSAEWOULDBLOCK festgelegt ist. Die Funktionen select, WSAAsyncSelect oder WSAEventSelect können verwendet werden, um zu bestimmen, wann mehr Daten eingehen.

Wenn der Socket verbindungsorientiert ist und die Remoteseite die Verbindung ordnungsgemäß heruntergefahren hat und alle Daten empfangen wurden, wird ein Recv sofort mit null empfangenen Bytes abgeschlossen. Wenn die Verbindung zurückgesetzt wurde, schlägt ein recv mit dem Fehler WSAECONNRESET fehl.

Der Flags-Parameter kann verwendet werden, um das Verhalten des Funktionsaufrufs über die für den zugeordneten Socket angegebenen Optionen hinaus zu beeinflussen. Die Semantik dieser Funktion wird durch die Socketoptionen und den Flags-Parameter bestimmt. Der mögliche Wert des Flags-Parameters wird mithilfe des bitweisen OR-Operators mit einem der folgenden Werte erstellt.

Wert Bedeutung
MSG_PEEK Hier werden die eingehenden Daten angezeigt. Die Daten werden in den Puffer kopiert, aber nicht aus der Eingabewarteschlange entfernt.
MSG_OOB Verarbeitet Out-of-Band-Daten (OOB).
MSG_WAITALL Die Empfangsanforderung wird nur abgeschlossen, wenn eines der folgenden Ereignisse auftritt:
  • Der vom Aufrufer bereitgestellte Puffer ist vollständig voll.
  • Die Verbindung wurde geschlossen.
  • Die Anforderung wurde abgebrochen, oder es ist ein Fehler aufgetreten.
Beachten Sie, dass dieser Aufruf mit WSAEOPNOTSUPP fehlschlägt, wenn der zugrunde liegende Transport MSG_WAITALL nicht unterstützt oder sich der Socket in einem nicht blockierenden Modus befindet. Wenn MSG_WAITALL zusammen mit MSG_OOB, MSG_PEEK oder MSG_PARTIAL angegeben wird, schlägt dieser Aufruf mit WSAEOPNOTSUPP fehl. Dieses Flag wird für Datagrammsockets oder nachrichtenorientierte Sockets nicht unterstützt.
 
Hinweis Wenn Sie einen blockierenden Winsock-Aufruf wie recv ausgeben, muss Winsock möglicherweise auf ein Netzwerkereignis warten, bevor der Anruf abgeschlossen werden kann. Winsock führt in dieser Situation eine warnbare Wartezeit aus, die durch einen asynchronen Prozeduraufruf (APC) unterbrochen werden kann, der für denselben Thread geplant ist. Das Ausstellen eines weiteren blockierenden Winsock-Aufrufs innerhalb eines APC, der einen fortlaufend blockierenden Winsock-Aufruf im selben Thread unterbrochen hat, führt zu undefiniertem Verhalten und darf niemals von Winsock-Clients versucht werden.
 

Beispielcode

Im folgenden Codebeispiel wird die Verwendung der recv-Funktion veranschaulicht.
#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"

int __cdecl main() {

    //----------------------
    // Declare and initialize variables.
    WSADATA wsaData;
    int iResult;

    SOCKET ConnectSocket = INVALID_SOCKET;
    struct sockaddr_in clientService; 

    char *sendbuf = "this is a test";
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
  
    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
      printf("WSAStartup failed: %d\n", iResult);
      return 1;
    }

    //----------------------
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return 1;
    }

    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port of the server to be connected to.
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    clientService.sin_port = htons( 27015 );

    //----------------------
    // Connect to server.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
    if ( iResult == SOCKET_ERROR) {
        closesocket (ConnectSocket);
        printf("Unable to connect to server: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf("send failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %ld\n", iResult);

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            printf("Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            printf("Connection closed\n");
        else
            printf("recv failed: %d\n", WSAGetLastError());

    } while( iResult > 0 );

    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}


Beispielcode

Weitere Informationen und ein weiteres Beispiel für die recv-Funktion finden Sie unter Erste Schritte Mit Winsock.

Windows Phone 8: Diese Funktion wird für Windows Phone Store-Apps ab Windows Phone 8 unterstützt.

Windows 8.1 und Windows Server 2012 R2: Diese Funktion wird für Windows Store-Apps unter Windows 8.1, Windows Server 2012 R2 und höher unterstützt.

Anforderungen

   
Unterstützte Mindestversion (Client) Windows 8.1, Windows Vista [Desktop-Apps | UWP-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [Desktop-Apps | UWP-Apps]
Zielplattform Windows
Kopfzeile winsock.h (Winsock2.h einschließen)
Bibliothek Ws2_32.lib
DLL Ws2_32.dll

Weitere Informationen

WSAAsyncSelect

WSARecv

WSARecvEx

Winsock-Funktionen

Winsock-Referenz

recvfrom

select

send

Socket