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 |
---|---|
Vor der Verwendung dieser Funktion muss ein erfolgreicher WSAStartup-Aufruf erfolgen. | |
Fehler beim Netzwerksubsystem. | |
Der buf-Parameter ist nicht vollständig in einem gültigen Teil des Benutzeradressraums enthalten. | |
Der Socket ist nicht verbunden. | |
Der (blockierende) Anruf wurde über WSACancelBlockingCall abgebrochen. | |
Ein blockierter Windows Sockets 1.1-Aufruf wird ausgeführt, oder der Dienstanbieter verarbeitet noch eine Rückruffunktion. | |
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. | |
Der Deskriptor ist kein Socket. | |
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. | |
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. | |
Der Socket wird als nicht blockiert markiert, und der Empfangsvorgang würde blockiert. | |
Die Nachricht war zu groß für den angegebenen Puffer und wurde abgeschnitten. | |
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. | |
Timeout- oder anderer Fehler. Die virtuelle Verbindung wurde beendet. Die Anwendung sollte den Socket schließen, weil er nicht mehr verwendbar ist. | |
Netzwerkfehler oder Antwortfehler des Peersystems. Die Verbindung wurde abgebrochen. | |
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:
|
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 |