LPWSPRECV-Rückruffunktion (ws2spi.h)

Die LPWSPRecv-Funktion empfängt Daten zu einem Socket.

Syntax

LPWSPRECV Lpwsprecv;

int Lpwsprecv(
  [in]         SOCKET s,
  \[in\, out\] LPWSABUF lpBuffers,
  [in]         DWORD dwBufferCount,
  [out]        LPDWORD lpNumberOfBytesRecvd,
  \[in\, out\] LPDWORD lpFlags,
  [in]         LPWSAOVERLAPPED lpOverlapped,
  [in]         LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  [in]         LPWSATHREADID lpThreadId,
  [out]        LPINT lpErrno
)
{...}

Parameter

[in] s

Ein Deskriptor, der einen verbundenen Socket identifiziert.

\\[in\\, out\\] lpBuffers

Ein Zeiger auf ein Array von WSABUF-Strukturen . Jede WSABUF-Struktur enthält einen Zeiger auf einen Puffer und die Länge des Puffers in Bytes.

[in] dwBufferCount

Die Anzahl der WSABUF-Strukturen im lpBuffers-Array .

[out] lpNumberOfBytesRecvd

Ein Zeiger auf die Anzahl der Bytes, die von diesem Aufruf empfangen werden.

\\[in\\, out\\] lpFlags

Ein Zeiger auf Flags, die die Art und Weise angeben, in der der Aufruf erfolgt.

[in] lpOverlapped

Ein Zeiger auf eine WSAOverlapped-Struktur (wird für nicht überlappende Strukturen ignoriert).

[in] lpCompletionRoutine

Typ: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

Ein Zeiger auf die Vervollständigungsroutine, die aufgerufen wird, wenn der Empfangsvorgang abgeschlossen wurde (wird für nicht überlappende Strukturen ignoriert).

[in] lpThreadId

Ein Zeiger auf eine WSATHREADID-Struktur , die vom Anbieter in einem nachfolgenden Aufruf von WPUQueueApc verwendet werden soll. Der Anbieter sollte die referenzierte WSATHREADID-Struktur (nicht den Zeiger auf dieselbe) speichern, bis die WPUQueueApc-Funktion zurückgegeben wird.

[out] lpErrno

Ein Zeiger auf den Fehlercode.

Rückgabewert

Wenn kein Fehler auftritt und der Empfangsvorgang sofort abgeschlossen wurde, gibt LPWSPRecv null zurück. Beachten Sie, dass in diesem Fall die Vervollständigungsroutine, sofern angegeben, bereits in die Warteschlange eingereiht wurde. Andernfalls wird der Wert SOCKET_ERROR zurückgegeben, und ein bestimmter Fehlercode ist in lpErrno verfügbar. Der Fehlercode WSA_IO_PENDING gibt an, dass der überlappende Vorgang erfolgreich initiiert wurde und dass der Abschluss zu einem späteren Zeitpunkt angezeigt wird. Jeder andere Fehlercode gibt an, dass keine überlappenden Vorgänge initiiert wurden und keine Vervollständigungsanzeige erfolgt.

Fehlercode Bedeutung
WSAENETDOWN
Fehler beim Netzwerksubsystem.
WSAENOTCONN
„Socket ist nicht verbunden.“
WSAEINTR
Der (Blockierende) Anruf wurde über LPWSPCancelBlockingCall abgebrochen.
WSAEINPROGRESS
Der Windows Sockets-Aufruf wird blockiert, oder der Dienstanbieter verarbeitet weiterhin eine Rückruffunktion.
WSAENETRESET
Die Verbindung wurde unterbrochen, weil eine Keep-Alive-Aktivität einen Fehler erkannt hat, während der Vorgang ausgeführt wurde.
WSAEFAULT
Der lpBuffers-Parameter ist nicht vollständig in einem gültigen Teil des Benutzeradressraums enthalten.
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
Socket wurde heruntergefahren; Es ist nicht möglich, über LPWSPRecv auf einem Socket zu empfangen, nachdem LPWSPShutdown aufgerufen wurde und wie auf SD_RECEIVE oder SD_BOTH festgelegt wurde.
WSAEWOULDBLOCK
Windows NT: Überlappende Sockets: Es gibt zu viele ausstehende überlappende E/A-Anforderungen. Nicht überlappende Sockets: Der Socket ist als nicht blockiert gekennzeichnet, und der Empfangsvorgang kann nicht sofort abgeschlossen werden.
WSAEMSGSIZE
Die Nachricht war zu groß, um in den angegebenen Puffer zu passen, und (nur für unzuverlässige Protokolle) wurde jeder nachfolgende Teil der Nachricht verworfen, der nicht in den Puffer passte.
WSAEINVAL
Der Socket wurde nicht gebunden (z. B. an LPWSPBind), oder der Socket wird nicht mit dem überlappenden Flag erstellt.
WSAECONNABORTED
Die virtuelle Verbindung wurde aufgrund eines Timeouts oder eines anderen Fehlers beendet.
WSAECONNRESET
Die virtuelle Verbindung wurde von der Remoteseite zurückgesetzt.
WSAEDISCON
Sockets ist nachrichtenorientiert, und die virtuelle Verbindung wurde von der Remoteseite ordnungsgemäß geschlossen.
WSA_IO_PENDING
Ein überlappender Vorgang wurde erfolgreich initiiert, und der Abschluss wird zu einem späteren Zeitpunkt angezeigt.
WSA_OPERATION_ABORTED
Der überlappende Vorgang wurde aufgrund der Schließung des Sockets abgebrochen.

Hinweise

LPWSPRecv wird für verbundene Sockets oder gebundene verbindungslose Sockets verwendet, die vom s-Parameter angegeben werden, und wird zum Lesen eingehender Daten verwendet. Die lokale Adresse des Sockets muss bekannt sein. Dies kann explizit über LPWSPBind oder implizit über LPWSPAccept, LPWSPConnect, LPWSPSendTo oder LPWSPJoinLeaf erfolgen.

Bei verbundenen, verbindungslosen Sockets schränkt diese 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 überlappende Sockets wird LPWSPRecv verwendet, um einen oder mehrere Puffer zu posten, in denen eingehende Daten platziert werden, sobald sie verfügbar werden. Danach erfolgt die clientspezifische Vervollständigungsanzeige von Windows Sockets SPI (Aufruf der Abschlussroutine oder Einstellung eines Ereignisobjekts). Wenn der Vorgang nicht sofort abgeschlossen wird, wird der endgültige Abschluss status über die Abschlussroutine oder LPWSPGetOverlappedResult abgerufen.

Wenn sowohl lpOverlapped als auch lpCompletionRoutine NULL sind, wird der Socket in dieser Funktion als nicht überlappter Socket behandelt.

Bei nicht überlappten Sockets werden die Parameter lpOverlapped, lpCompletionRoutine und lpThreadId ignoriert. Alle Daten, die bereits vom Transport empfangen und gepuffert wurden, werden in die bereitgestellten Benutzerpuffer kopiert. Im Fall eines blockierenden Sockets, bei dem derzeit keine Daten empfangen und vom Transport gepuffert wurden, wird der Aufruf blockiert, bis Daten empfangen werden. Windows Sockets 2 definiert keinen standardmäßigen Blockierungstimeoutmechanismus für diese Funktion. Bei Protokollen, die als Bytestreamprotokolle fungieren, versucht der Stapel, so viele Daten wie möglich zurückzugeben, abhängig vom angegebenen Pufferspeicherplatz und der menge der empfangenen Daten, die verfügbar sind. Der Empfang eines einzelnen Byte reicht jedoch aus, um die Blockierung des Aufrufers aufzuheben. Es gibt keine Garantie, dass mehr als ein einzelnes Byte zurückgegeben wird. Für Protokolle, die als nachrichtenorientiert fungieren, ist eine vollständige Nachricht erforderlich, um die Blockierung des Aufrufers aufzuheben.

Ob ein Protokoll als Bytestream fungiert, wird durch die Einstellung von XP1_MESSAGE_ORIENTED und XP1_PSEUDO_STREAM in seiner WSAPROTOCOL_INFO-Struktur und der Einstellung des MSG_PARTIAL Flags bestimmt, das an diese Funktion übergeben wird (für Protokolle, die dies unterstützen). Die relevanten Kombinationen sind in der folgenden Tabelle zusammengefasst (ein Sternchen (*) gibt an, dass die Einstellung dieses Bits in diesem Fall keine Rolle spielt).

XP1_MESSAGE_ORIENTED XP1_PSEUDO_STREAM MSG_PARTIAL Fungiert als
nicht festgelegt * * Bytestream
* set * Bytestream
set nicht festgelegt set Bytestream
set nicht festgelegt nicht festgelegt nachrichtenorientiert

Die bereitgestellten Puffer werden in der Reihenfolge gefüllt, in der sie im Array angezeigt werden, auf das von lpBuffers verwiesen wird, und die Puffer werden gepackt, sodass keine Löcher erstellt werden.

Das Array von WSABUF-Strukturen , auf das der lpBuffers-Parameter verweist, ist vorübergehend. Wenn dieser Vorgang auf überlappende Weise abgeschlossen wird, liegt es in der Verantwortung des Dienstanbieters, dieses Array von Zeigern auf WSABUF-Strukturen zu erfassen, bevor von diesem Aufruf zurückgegeben wird. Dadurch können Windows Sockets SPI-Clients stapelbasierte WSABUF-Arrays erstellen.

Bei Bytestreamsockets (z. B. Typ SOCK_STREAM) werden eingehende Daten in die Puffer platziert, bis die Puffer gefüllt, die Verbindung geschlossen oder intern gepufferte Daten erschöpft sind. Unabhängig davon, ob die eingehenden Daten alle Puffer füllen, tritt die Vervollständigungsanzeige für überlappende Sockets auf. Für nachrichtenorientierte Sockets (z. B. Typ SOCK_DGRAM) wird eine eingehende Nachricht bis zur Gesamtgröße der bereitgestellten Puffer in die bereitgestellten Puffer platziert, und die Abschlussanzeige tritt bei überlappenden Sockets auf. Wenn die Nachricht größer als die bereitgestellten Puffer ist, werden die Puffer mit dem ersten Teil der Nachricht gefüllt. Wenn die MSG_PARTIAL-Funktion vom Dienstanbieter unterstützt wird, wird das MSG_PARTIAL-Flag in lpFlags festgelegt, und nachfolgende Empfangsvorgänge können verwendet werden, um den Rest der Nachricht abzurufen. Wenn MSG_PARTIAL nicht unterstützt wird, aber das Protokoll zuverlässig ist, generiert LPWSPRecv den Fehler WSAEMSGSIZE , und ein nachfolgender Empfangsvorgang mit einem größeren Puffer kann verwendet werden, um die gesamte Nachricht abzurufen. Andernfalls (das Protokoll ist unzuverlässig und unterstützt MSG_PARTIAL nicht) geht die überschüssigen Daten verloren, und LPWSPRecv generiert den Fehler WSAEMSGSIZE.

Für verbindungsorientierte Sockets kann LPWSPRecv die ordnungsgemäße Beendigung der virtuellen Verbindung auf eine von zwei Arten angeben, je nachdem, ob der Socket ein Bytedatenstrom oder nachrichtenorientiert ist. Bei Bytedatenströmen bedeutet das Lesen von null Bytes einen ordnungsgemäßen Abschluss, und es werden keine Bytes mehr gelesen. Für nachrichtenorientierte Sockets, bei denen eine Null-Byte-Nachricht häufig zulässig ist, wird ein Rückgabefehlercode von WSAEDISCON verwendet, um einen ordnungsgemäßen Abschluss anzuzeigen. In jedem Fall gibt ein Rückgabefehlercode von WSAECONNRESET an, dass ein abgebrochener Abschluss aufgetreten ist.

Der lpFlags-Parameter kann verwendet werden, um das Verhalten des Funktionsaufrufs über die für den zugeordneten Socket angegebenen Optionen hinaus zu beeinflussen. Das heißt, die Semantik dieser Funktion wird durch die Socketoptionen und den lpFlags-Parameter bestimmt. Letzteres 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. Dieses Flag ist nur für nicht überlappte Sockets gültig.
MSG_OOB Verarbeitet Out-of-Band-Daten (OOB).
MSG_PARTIAL Dieses Flag gilt nur für nachrichtenorientierte Sockets. Gibt bei der Ausgabe an, dass die bereitgestellten Daten ein Teil der nachricht sind, die vom Absender übertragen wird. Die verbleibenden Teile der Nachricht werden in nachfolgenden Empfangsvorgängen bereitgestellt. Ein nachfolgender Empfangsvorgang mit MSG_PARTIAL deaktiviertem Flag gibt das Ende der Nachricht des Absenders an. Als Eingabeparameter gibt MSG_PARTIAL an, dass der Empfangsvorgang auch dann abgeschlossen werden soll, wenn nur ein Teil einer Nachricht vom Dienstanbieter empfangen wurde.

Wenn ein überlappender Vorgang sofort abgeschlossen wird, gibt LPWSPRecv den Wert 0 (null) zurück, und der parameter lpNumberOfBytesRecvd wird mit der Anzahl der empfangenen Bytes aktualisiert, und die vom lpFlags-Parameter gezeigten Flagbits werden ebenfalls aktualisiert. Wenn der überlappende Vorgang erfolgreich initiiert wurde und später abgeschlossen wird, gibt LPWSPRecv SOCKET_ERROR zurück und gibt den Fehlercode WSA_IO_PENDING an. In diesem Fall werden lpNumberOfBytesRecvd und lpFlags nicht aktualisiert. Wenn der überlappende Vorgang abgeschlossen ist, wird die übertragene Datenmenge entweder über den cbTransferred-Parameter in der Abschlussroutine (sofern angegeben) oder über den lpcbTransfer-Parameter in LPWSPGetOverlappedResult angegeben. Flagwerte werden entweder über den dwFlags-Parameter der Abschlussroutine oder durch Untersuchen des lpdwFlags-Parameters von WSAGetOverlappedResult abgerufen.

Anbieter müssen zulassen, dass diese Funktion innerhalb der Vervollständigungsroutine einer früheren LPWSPRecv-, LPWSPRecvFrom-, LPWSPSend- oder LPWSPSendTo-Funktion aufgerufen wird. Für einen bestimmten Socket können E/A-Vervollständigungsroutinen jedoch nicht geschachtelt werden. Dadurch können zeitkritische Datenübertragungen vollständig in einem präemptiven Kontext erfolgen.

Der lpOverlapped-Parameter muss für die Dauer des überlappenden Vorgangs gültig sein. Wenn mehrere E/A-Vorgänge gleichzeitig ausstehen, muss jeder auf eine separate überlappende Struktur verweisen. Die WSAOverlapped-Struktur wird auf einer eigenen Referenzseite definiert.

Wenn der lpCompletionRoutine-Parameter NULL ist, signalisiert der Dienstanbieter den hEvent-Member von lpOverlapped , wenn der überlappende Vorgang abgeschlossen ist, wenn er ein gültiges Ereignisobjekthandle enthält. Der Windows Sockets SPI-Client kann LPWSPGetOverlappedResult verwenden, um auf das Ereignisobjekt zu warten oder abzufragen.

Wenn lpCompletionRoutine nicht NULL ist, wird das hEvent-Element ignoriert und kann vom SPI-Client von Windows Sockets verwendet werden, um Kontextinformationen an die Vervollständigungsroutine zu übergeben. Ein Client, der null lpCompletionRoutine übergibt und später WSAGetOverlappedResult für dieselbe überlappende E/A-Anforderung aufruft, legt den fWait-Parameter für diesen Aufruf von WSAGetOverlappedResult möglicherweise nicht auf TRUE fest. In diesem Fall ist die Verwendung des hEvent-Members nicht definiert, und der Versuch, auf das hEvent-Element zu warten, würde zu unvorhersehbaren Ergebnissen führen.

Es liegt in der Verantwortung des Dienstanbieters, den Aufruf der vom Client angegebenen Vervollständigungsroutine zu veranlassen, wenn der überlappende Vorgang abgeschlossen ist. Da die Vervollständigungsroutine im Kontext desselben Threads ausgeführt werden muss, der den überlappenden Vorgang initiiert hat, kann sie nicht direkt vom Dienstanbieter aufgerufen werden. Die Ws2_32.dll bietet einen APC-Mechanismus (asynchroner Prozeduraufruf), um den Aufruf von Abschlussroutinen zu erleichtern.

Ein Dienstanbieter sorgt dafür, dass eine Funktion im richtigen Thread- und Prozesskontext ausgeführt wird, indem er WPUQueueApc aufruft, das zum Initiieren des überlappenden Vorgangs verwendet wurde. Diese Funktion kann aus jedem Prozess- und Threadkontext aufgerufen werden, sogar aus einem anderen Kontext als dem Thread und Prozess, der zum Initiieren des überlappenden Vorgangs verwendet wurde.

WPUQueueApc verwendet als Eingabeparameter einen Zeiger auf eine WSATHREADID-Struktur (die dem Anbieter über den lpThreadId-Eingabeparameter bereitgestellt wird), einen Zeiger auf eine aufzurufende APC-Funktion und einen Kontextwert, der anschließend an die APC-Funktion übergeben wird. Da nur ein einzelner Kontextwert verfügbar ist, kann die APC-Funktion selbst nicht die vom Client angegebene Vervollständigungsroutine sein. Der Dienstanbieter muss stattdessen einen Zeiger auf seine eigene APC-Funktion bereitstellen, die den angegebenen Kontextwert verwendet, um auf die erforderlichen Ergebnisinformationen für den überlappenden Vorgang zuzugreifen, und dann die vom Client angegebene Vervollständigungsroutine aufruft.

Der Prototyp für die vom Client bereitgestellte Vervollständigungsroutine sieht wie folgt aus.

void CALLBACK 
CompletionRoutine(  
  IN DWORD           dwError, 
  IN DWORD           cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD           dwFlags 
);

Der CompletionRoutine-Parameter ist ein Platzhalter für einen vom Client bereitgestellten Funktionsnamen. dwError gibt den Abschluss status für den überlappenden Vorgang an, wie durch lpOverlapped angegeben. Der cbTransferred-Parameter gibt die Anzahl der empfangenen Bytes an. dwFlags enthält Informationen, die in lpFlags angezeigt worden wären, wenn der Empfangsvorgang sofort abgeschlossen worden wäre. Diese Funktion gibt keinen Wert zurück.

Die Vervollständigungsroutinen können in beliebiger Reihenfolge aufgerufen werden, aber nicht notwendigerweise in derselben Reihenfolge, in der die überlappenden Vorgänge abgeschlossen werden. Die bereitgestellten Puffer werden jedoch garantiert in derselben Reihenfolge ausgefüllt, in der sie bereitgestellt werden.

Hinweis

Alle von einem bestimmten Thread initiierten E/A-Vorgänge werden abgebrochen, wenn dieser Thread beendet wird. Bei überlappenden Sockets können ausstehende asynchrone Vorgänge fehlschlagen, wenn der Thread geschlossen wird, bevor die Vorgänge abgeschlossen sind. Weitere Informationen finden Sie unter ExitThread .

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows 10 Build 20348
Unterstützte Mindestversion (Server) Windows 10 Build 20348
Kopfzeile ws2spi.h

Weitere Informationen

WPUCloseEvent

WPUCreateEvent

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket