LPFN_WSARECVMSG Rückruffunktion (mswsock.h)
LPFN_WSARECVMSG ist ein Funktionszeigertyp. Sie implementieren eine entsprechende WSARecvMsg-Rückruffunktion in Ihrer App. Das System verwendet Ihre Rückruffunktion, um In-Memory-Daten oder Dateidaten über einen verbundenen Socket an Sie zu übertragen.
Ihre WSARecvMsg-Rückruffunktion empfängt zusätzliche Daten-/Steuerungsinformationen mit einer Nachricht von verbundenen und nicht verbundenen Sockets.
Hinweis
Diese Funktion ist eine Microsoft-spezifische Erweiterung der Windows Sockets-Spezifikation.
Syntax
LPFN_WSARECVMSG LpfnWsarecvmsg;
INT LpfnWsarecvmsg(
SOCKET s,
LPWSAMSG lpMsg,
LPDWORD lpdwNumberOfBytesRecvd,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
{...}
Parameter
s
Typ: _In_ SOCKET
Ein Deskriptor, der den Socket identifiziert.
lpMsg
Typ: _Inout_ LPWSAMSG
Ein Zeiger auf eine WSAMSG-Struktur , die auf der Posix.1g-Spezifikation für die msghdr-Struktur basiert.
lpdwNumberOfBytesRecvd
Typ: _Out_opt_ LPDWORD
Ein Zeiger auf ein DWORD mit der Anzahl von Bytes, die von diesem Aufruf empfangen werden, wenn der WSARecvMsg-Vorgang sofort abgeschlossen wird.
Um potenziell fehlerhafte Ergebnisse zu vermeiden, übergeben Sie NULL für diesen Parameter, wenn der lpOverlapped-Parameter nicht NULL ist. Dieser Parameter kann nur NULL sein, wenn der lpOverlapped-Parameter nicht NULL ist.
lpOverlapped
Typ: _Inout_opt_ LPWSAOVERLAPPED
Ein Zeiger auf eine WSAOVERLAPPED-Struktur . Wird für nicht überlappende Strukturen ignoriert.
lpCompletionRoutine
Typ: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
Ein Zeiger auf die Vervollständigungsroutine, die aufgerufen wird, wenn der Empfangsvorgang abgeschlossen ist. Wird für nicht überlappende Strukturen ignoriert.
Rückgabewert
Wenn kein Fehler auftritt und der Empfangsvorgang sofort abgeschlossen wurde, gibt WSARecvMsg null zurück. In diesem Fall wurde der Aufruf der Vervollständigungsroutine bereits geplant, sobald sich der aufrufende Thread im warnbaren Zustand befindet. Andernfalls wird der Wert SOCKET_ERROR zurückgegeben, und ein bestimmter Fehlercode kann durch Aufrufen von WSAGetLastError abgerufen werden. 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 der Vorgang nicht erfolgreich initiiert wurde, und es wird kein Abschlusshinweis angezeigt, wenn ein überlappender Vorgang angefordert wurde.
Fehlercode | Bedeutung |
---|---|
WSAECONNRESET | Bei einem UDP-Datagrammsocket würde dieser Fehler darauf hindeuten, dass ein vorheriger Sendevorgang zu einer ICMP-Meldung "Port unreachable" geführt hat. |
WSAEFAULT | Die Parameter lpBuffers, lpFlags, lpFrom, lpNumberOfBytesRecvd, lpFromlen, lpOverlapped oder lpCompletionRoutine sind nicht vollständig in einem gültigen Teil des Benutzeradressraums enthalten: Der puffer lpFrom war zu klein, um die Peeradresse aufzunehmen. Dieser Fehler wird auch zurückgegeben, wenn ein Namensmember der WSAMSG-Struktur , auf die der lpMsg-Parameter verweist, ein NULL-Zeiger war und der namelen-Member der WSAMSG-Struktur nicht auf 0 festgelegt wurde. Dieser Fehler wird auch zurückgegeben, wenn ein Control.buf-Member der WSAMSG-Struktur , auf die der lpMsg-Parameter verweist, ein NULL-Zeiger war und das Control.len-Element der WSAMSG-Struktur nicht auf 0 festgelegt wurde. |
WSAEINPROGRESS | Ein blockierter Windows Sockets 1.1-Aufruf wird ausgeführt, oder der Dienstanbieter verarbeitet noch eine Rückruffunktion. |
WSAEINTR | Ein blockierender Windows Socket 1.1-Aufruf wurde über WSACancelBlockingCall abgebrochen. |
WSAEINVAL | Der Socket wurde nicht gebunden (z. B. mit bindung). |
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. |
WSAENETDOWN | Fehler beim Netzwerksubsystem. |
WSAENETRESET | Für einen Datagrammsocket zeigt dieser Fehler an, dass die Gültigkeitsdauer abgelaufen ist. |
WSAENOTCONN | Der Socket ist nicht verbunden (nur verbindungsorientierte Sockets). |
WSAETIMEDOUT | Timeout des Sockets. Dieser Fehler wird zurückgegeben, wenn für den Socket ein Wartetimeout mit der Socketoption SO_RCVTIMEO angegeben wurde und das Timeout überschritten wurde. |
WSAEOPNOTSUPP | Der Socketvorgang wird nicht unterstützt. Dieser Fehler wird zurückgegeben, wenn der dwFlags-Member der WSAMSG-Struktur, auf die der lpMsg-Parameter verweist, das MSG_PEEK-Steuerelementflag in einem Nicht-Datagrammsocket enthält. |
WSAEWOULDBLOCK | Windows NT: Überlappende Sockets: Es gibt zu viele ausstehende überlappende E/A-Anforderungen. Nicht überlappende Sockets: Der Socket ist als nicht blockierend gekennzeichnet, und der Empfangsvorgang kann nicht sofort abgeschlossen werden. |
WSANOTINITIALISIERT | Vor der Verwendung dieser Funktion muss ein erfolgreicher WSAStartup-Aufruf erfolgen. |
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 des Schließens des Sockets abgebrochen. |
Hinweise
Die WSARecvMsg-Funktion kann anstelle der Funktionen WSARecv und WSARecvFrom verwendet werden, um Daten und optionale Steuerinformationen von verbundenen und nicht verbundenen Sockets zu empfangen. Die WSARecvMsg-Funktion kann nur mit Datagrammen und unformatierten Sockets verwendet werden. Der Socketdeskriptor im s-Parameter muss geöffnet werden, wobei der Sockettyp auf SOCK_DGRAM oder SOCK_RAW festgelegt ist.
Hinweis Der Funktionszeiger für die WSARecvMsg-Funktion muss zur Laufzeit abgerufen werden, indem die WSAIoctl-Funktion mit dem angegebenen SIO_GET_EXTENSION_FUNCTION_POINTER Opcode aufgerufen wird. Der an die WSAIoctl-Funktion übergebene Eingabepuffer muss WSAID_WSARECVMSG enthalten, einen GUID (Globally Unique Identifier), dessen Wert die WSARecvMsg-Erweiterungsfunktion identifiziert. Bei Erfolg enthält die von der WSAIoctl-Funktion zurückgegebene Ausgabe einen Zeiger auf die WSARecvMsg-Funktion . Die WSAID_WSARECVMSG GUID ist in der Headerdatei Mswsock.h definiert.
Der dwFlags-Member der WSAMSG-Struktur, auf die der lpMsg-Parameter verweist, darf bei der Eingabe nur das MSG_PEEK-Steuerelementflag enthalten.
Überlappende Sockets werden mit einem WSASocket-Funktionsaufruf erstellt, für den das flag WSA_FLAG_OVERLAPPED festgelegt ist. Für überlappende Sockets verwendet der Empfang von Informationen überlappende E/A, es sei denn, die Parameter lpOverlapped und lpCompletionRoutine sind NULL. Der Socket wird als nicht überlappender Socket behandelt, wenn sowohl die Parameter lpOverlapped als auch lpCompletionRoutineNULL sind.
Eine Vervollständigungsanzeige tritt mit überlappenden Sockets auf. Nachdem der Puffer oder die Puffer vom Transport verbraucht wurden, wird eine Vervollständigungsroutine ausgelöst oder ein Ereignisobjekt festgelegt. Wenn der Vorgang nicht sofort abgeschlossen wird, wird der endgültige Abschluss status über die Vervollständigungsroutine oder durch Aufrufen der WSAGetOverlappedResult-Funktion abgerufen.
Für überlappende Sockets wird WSARecvMsg verwendet, um einen oder mehrere Puffer zu posten, in denen eingehende Daten platziert werden, sobald sie verfügbar werden, worauf die anwendungsspezifische Vervollständigungsanzeige (Aufruf der Vervollständigungsroutine oder Einstellung eines Ereignisobjekts) erfolgt. Wenn der Vorgang nicht sofort abgeschlossen wird, wird der endgültige Abschluss status über die Vervollständigungsroutine oder die WSAGetOverlappedResult-Funktion abgerufen.
Bei nicht überlappenden Sockets ist die blockierende Semantik mit der der recv-Standardfunktion identisch, und die Parameter lpOverlapped und lpCompletionRoutine werden ignoriert. Alle Daten, die bereits vom Transport empfangen und gepuffert wurden, werden in die angegebenen 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 verfügbaren 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.
Hinweis Die Option SO_RCVTIMEO Sockets gilt nur für blockierende Sockets.
Die Puffer werden in der Reihenfolge gefüllt, in der sie im Array angezeigt werden, auf das der lpBuffers-Member der WSAMSG-Struktur verweist, auf die der lpMsg-Parameter verweist, und die Puffer werden gepackt, sodass keine Löcher erstellt werden.
Wenn diese Funktion überlappend ausgeführt wird, liegt es in der Verantwortung des Winsock-Dienstanbieters, diese WSABUF-Struktur zu erfassen, bevor sie von diesem Aufruf zurückgegeben wird. Dadurch können Anwendungen stapelbasierte WSABUF-Arrays erstellen, auf die der lpBuffers-Member der WSAMSG-Struktur verweist, auf die der lpMsg-Parameter verweist.
Für nachrichtenorientierte Sockets (ein Sockettyp von SOCK_DGRAM oder SOCK_RAW) wird eine eingehende Nachricht in die Puffer bis zur Gesamtgröße der Puffer platziert, und die Vervollständigungsanzeige tritt bei überlappenden Sockets auf. Wenn die Nachricht größer als die Puffer ist, werden die Puffer mit dem ersten Teil der Nachricht gefüllt, und die überschüssigen Daten gehen verloren, und WSARecvMsg generiert den Fehler WSAEMSGSIZE.
Wenn die Option IP_PKTINFO Socket für einen IPv4-Socket vom Typ SOCK_DGRAM oder SOCK_RAW aktiviert ist, gibt die WSARecvMsg-Funktion Paketinformationen in der WSAMSG-Struktur zurück, auf die der parameter lpMsg verweist. Eines der Steuerelementdatenobjekte in der zurückgegebenen WSAMSG-Struktur enthält eine in_pktinfo-Struktur , die zum Speichern empfangener Paketadresseninformationen verwendet wird.
Für Datagramme, die über IPv4 empfangen werden, enthält das Control-Element der empfangenen WSAMSG-Struktur eine WSABUF-Struktur , die eine WSACMSGHDR-Struktur enthält. Der cmsg_level Member dieser WSACMSGHDR-Struktur würde IPPROTO_IP enthalten, das cmsg_type-Element dieser Struktur würde IP_PKTINFO und das cmsg_data-Element eine in_pktinfo-Struktur enthalten, die zum Speichern empfangener IPv4-Paketadresseninformationen verwendet wird. Die IPv4-Adresse in der in_pktinfo-Struktur ist die IPv4-Adresse, von der das Paket empfangen wurde.
Wenn die Option IPV6_PKTINFO Sockets für einen IPv6-Socket vom Typ SOCK_DGRAM oder SOCK_RAW aktiviert ist, gibt die WSARecvMsg-Funktion Paketinformationen in der WSAMSG-Struktur zurück, auf die der parameter lpMsg verweist. Eines der Steuerelementdatenobjekte in der zurückgegebenen WSAMSG-Struktur enthält eine in6_pktinfo Struktur, die zum Speichern empfangener Paketadresseninformationen verwendet wird.
Für Datagramme, die über IPv6 empfangen werden, enthält das Control-Element der empfangenen WSAMSG-Struktur eine WSABUF-Struktur , die eine WSACMSGHDR-Struktur enthält. Der cmsg_level Member dieser WSACMSGHDR-Struktur würde IPPROTO_IPV6 enthalten, das cmsg_type-Element dieser Struktur würde IPV6_PKTINFO und das cmsg_data-Element eine in6_pktinfo-Struktur enthalten, die zum Speichern empfangener IPv6-Paketadresseninformationen verwendet wird. Die IPv6-Adresse in der in6_pktinfo-Struktur ist die IPv6-Adresse, von der das Paket empfangen wurde.
Wenn eine Anwendung für einen Dual-Stack-Datagrammsocket erfordert, dass die WSARecvMsg-Funktion Paketinformationen in einer WSAMSG-Struktur für Datagramme zurückgibt, die über IPv4 empfangen werden, muss IP_PKTINFO Socketoption für den Socket auf true festgelegt werden. Wenn nur die Option IPV6_PKTINFO im Socket auf true festgelegt ist, werden Paketinformationen für Datagramme bereitgestellt, die über IPv6 empfangen wurden, aber möglicherweise nicht für Datagramme, die über IPv4 empfangen werden.
Beachten Sie, dass die Ws2ipdef.h-Headerdatei automatisch in Ws2tcpip.h enthalten ist und niemals direkt verwendet werden sollte.
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.
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 auf Windows 8.1, Windows Server 2012 R2 und höher unterstützt.
dwFlags
Bei der Eingabe kann der dwFlags-Member der WSAMSG-Struktur , auf die der lpMsg-Parameter verweist, verwendet werden, um das Verhalten des Funktionsaufrufs über die Socketoptionen hinaus zu beeinflussen, die für den zugeordneten Socket angegeben sind. Das heißt, die Semantik dieser Funktion wird durch die Socketoptionen und den dwFlags-Member der WSAMSG-Struktur bestimmt. Der einzige mögliche Eingabewert für den dwFlags-Member der WSAMSG-Struktur , auf die der lpMsg-Parameter verweist, ist MSG_PEEK.
Wert | Bedeutung |
---|---|
MSG_PEEK | Peek an den eingehenden Daten. Die Daten werden in den Puffer kopiert, aber nicht aus der Eingabewarteschlange entfernt. Dieses Flag ist nur für nicht überlappende Sockets gültig. |
Die möglichen Werte für dwFlags-Member bei der Eingabe sind in der Winsock2.h-Headerdatei definiert.
Bei der Ausgabe gibt der dwFlags-Member der WSAMSG-Struktur , auf die der lpMsg-Parameter verweist, eine Kombination aus einem der folgenden Werte zurück.
Wert | Bedeutung |
---|---|
MSG_BCAST | Das Datagramm wurde als Broadcast auf Linkebene oder mit einer Ziel-IP-Adresse empfangen, bei der es sich um eine Broadcastadresse handelt. |
MSG_CTRUNC | Die Steuerelementdaten (Hilfsdaten) wurden abgeschnitten. Es waren mehr Steuerungsdaten vorhanden, als dem Prozess zugewiesen wurde. |
MSG_MCAST | Das Datagramm wurde mit einer Ziel-IP-Adresse empfangen, bei der es sich um eine Multicastadresse handelt. |
MSG_TRUNC | Das Datagramm wurde abgeschnitten. Es waren mehr Daten vorhanden, als dem Prozess zugewiesen wurde. |
Auf dem für Windows Vista und höher veröffentlichten Microsoft Windows Software Development Kit (SDK) wurde die organization der Headerdateien geändert, und die möglichen Werte für den dwFlags-Member bei der Ausgabe sind in der Ws2def.h-Headerdatei definiert, die automatisch in der Winsock2.h-Headerdatei enthalten ist.
In Versionen des Platform Software Development Kit (SDK) für Windows Server 2003 und früher werden die möglichen Werte für den dwFlags-Member bei der Ausgabe in der Headerdatei Mswsock.h definiert.
Hinweis Wenn Sie einen blockierenden Winsock-Aufruf wie WSARecvMsg ausgeben, bei dem der parameter lpOverlapped auf NULL festgelegt ist, muss Winsock möglicherweise auf ein Netzwerkereignis warten, bevor der Aufruf 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.
Überlappende Socket-E/A
Wenn ein überlappender Vorgang sofort abgeschlossen wird, gibt WSARecvMsg den Wert 0 (null) zurück, und der Parameter lpNumberOfBytesRecvd wird mit der Anzahl der empfangenen Bytes aktualisiert, und die vom lpFlags-Parameter angegebenen Flagbits werden ebenfalls aktualisiert. Wenn der überlappende Vorgang erfolgreich initiiert wurde und später abgeschlossen wird, gibt WSARecvMsgSOCKET_ERROR zurück und gibt den Fehlercode WSA_IO_PENDING an. In diesem Fall wird lpNumberOfBytesRecvd 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 WSAGetOverlappedResult angegeben. Flagwerte werden abgerufen, indem der lpdwFlags-Parameter von WSAGetOverlappedResult untersucht wird.
Die WSARecvMsg-Funktion mit überlappenden E/A-Vorgängen kann innerhalb der Vervollständigungsroutine einer vorherigen WSARecv,WSARecvFrom-, WSARecvMsg-, WSASend-, WSASendMsg- oder WSASendTo-Funktion aufgerufen werden. Für einen bestimmten Socket werden E/A-Abschlussroutinen nicht geschachtelt. 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 WSAOVERLAPPED-Struktur verweisen.
Wenn der lpCompletionRoutine-ParameterNULL ist, wird der hEvent-Parameter von lpOverlapped signalisiert, wenn der überlappende Vorgang abgeschlossen ist, wenn er ein gültiges Ereignisobjekthandle enthält. Eine Anwendung kann WSAWaitForMultipleEvents oder WSAGetOverlappedResult verwenden, um auf das Ereignisobjekt zu warten oder abzufragen.
Wenn lpCompletionRoutine nicht NULL ist, wird der hEvent-Parameter ignoriert und kann von der Anwendung verwendet werden, um Kontextinformationen an die Vervollständigungsroutine zu übergeben. Ein Aufrufer, der eine lpCompletionRoutine ungleich NULL ü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-Parameters nicht definiert, und der Versuch, auf den hEvent-Parameter zu warten, würde zu unvorhersehbaren Ergebnissen führen.
Die Vervollständigungsroutine folgt den gleichen Regeln wie für Windows-Datei-E/A-Vervollständigungsroutinen. Die Vervollständigungsroutine wird erst aufgerufen, wenn sich der Thread in einem warnbaren Wartezustand befindet, z. B. wenn die Funktion WSAWaitForMultipleEvents mit dem fAlertable-Parameter auf TRUE aufgerufen wird.
Der Prototyp der Vervollständigungsroutine sieht wie folgt aus:
void CALLBACK CompletionRoutine(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
Die CompletionRoutine ist ein Platzhalter für einen anwendungsdefinierte oder bibliotheksdefinierte Funktionsnamen. Der dwError-Parameter gibt den Abschluss status für den überlappenden Vorgang an, wie durch den lpOverlapped-Parameter angegeben. Der cbTransferred-Parameter gibt die Anzahl der empfangenen Bytes an. Der dwFlags-Parameter enthält Informationen, die auch im dwFlags-Member der WSAMSG-Struktur zurückgegeben werden, auf die der lpMsg-Parameter verweist, wenn der Empfangsvorgang sofort abgeschlossen wurde. Die CompletionRoutine-Funktion gibt keinen Wert zurück.
Die Rückgabe von dieser Funktion ermöglicht den Aufruf einer weiteren ausstehenden Vervollständigungsroutine für diesen Socket. Bei Verwendung von WSAWaitForMultipleEvents werden alle wartenden Vervollständigungsroutinen aufgerufen, bevor die Wartedauer des warnbaren Threads mit dem Rückgabecode WSA_IO_COMPLETION. Die Vervollständigungsroutinen können in beliebiger Reihenfolge aufgerufen werden, nicht unbedingt 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 angegeben sind.
Wenn Sie E/A-Vervollständigungsports verwenden, beachten Sie, dass die Reihenfolge der Aufrufe an WSARecvMsg auch die Reihenfolge ist, in der die Puffer aufgefüllt werden. Die WSARecvMsg-Funktion sollte nicht gleichzeitig für denselben Socket von verschiedenen Threads aufgerufen werden, da dies zu einer unvorhersehbaren Pufferreihenfolge führen kann.
Anforderungen
Anforderung | Wert |
---|---|
Unterstützte Mindestversion (Client) | Windows 10 Build 20348 |
Unterstützte Mindestversion (Server) | Windows 10 Build 20348 |
Kopfzeile | mswsock.h |