LPWSPRECVFROM-Rückruffunktion (ws2spi.h)
Die LPWSPRecvFrom-Funktion empfängt ein Datagramm und speichert die Quelladresse.
Syntax
LPWSPRECVFROM Lpwsprecvfrom;
int Lpwsprecvfrom(
[in] SOCKET s,
[in, out] LPWSABUF lpBuffers,
[in] DWORD dwBufferCount,
[out] LPDWORD lpNumberOfBytesRecvd,
[in, out] LPDWORD lpFlags,
[out] sockaddr *lpFrom,
[in, out] LPINT lpFromlen,
[in] LPWSAOVERLAPPED lpOverlapped,
[in] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
\[in\] LPWSATHREADID lpThreadId,
[in, out] LPINT lpErrno
)
{...}
Parameter
[in] s
Deskriptor, der einen Socket identifiziert.
[in, out] lpBuffers
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
Anzahl der WSABUF-Strukturen im lpBuffers-Array .
[out] lpNumberOfBytesRecvd
Zeiger auf die Anzahl der Von diesem Aufruf empfangenen Bytes.
[in, out] lpFlags
Zeiger auf Flags.
[out] lpFrom
Optionaler Zeiger auf einen Puffer in der Sockaddr-Struktur , der nach Abschluss des überlappenden Vorgangs die Quelladresse enthält.
[in, out] lpFromlen
Zeiger auf die Größe des puffers lpFrom in Bytes, nur erforderlich, wenn lpFrom angegeben ist.
[in] lpOverlapped
Zeiger auf eine WSAOverlapped-Struktur (bei nicht überlappten Sockets ignoriert).
[in] lpCompletionRoutine
Typ: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
Zeiger auf die Vervollständigungsroutine, die aufgerufen wird, wenn der Empfangsvorgang abgeschlossen wurde (bei nicht überlappten Sockets ignoriert).
\\[in\\] lpThreadId
Zeiger auf eine WSATHREADID-Struktur , die vom Anbieter in einem nachfolgenden Aufruf von WPUQueueApc verwendet werden soll. Der Anbieter sollte die WSATHREADID-Struktur (nicht den Zeiger auf dieselbe) speichern, bis die WPUQueueApc-Funktion zurückgegeben wird.
[in, out] lpErrno
Zeiger auf den Fehlercode.
Rückgabewert
Wenn kein Fehler auftritt und der Empfangsvorgang sofort abgeschlossen wurde, gibt LPWSPRecvFrom 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 die Vervollständigung zu einem späteren Zeitpunkt angezeigt wird. Jeder andere Fehlercode gibt an, dass keine überlappenden Vorgänge initiiert wurden und keine Vervollständigungsanzeige auftritt.
Fehlercode | Bedeutung |
---|---|
Beim Netzwerksubsystem ist ein Fehler aufgetreten. | |
Der lpFromlen-Parameter war ungültig: Der puffer lpFrom war zu klein, um die Peeradresse aufzunehmen, oder lpbuffers ist nicht vollständig in einem gültigen Teil des Benutzeradressraums enthalten. | |
Der (blockierende) Aufruf wurde über LPWSPCancelBlockingCall abgebrochen. | |
Der Windows Sockets-Aufruf wird blockiert, oder der Dienstanbieter verarbeitet weiterhin eine Rückruffunktion. | |
Der Socket wurde nicht gebunden (z. B. mit LPWSPBind), oder der Socket wird nicht mit dem überlappenden Flag erstellt. | |
Socket ist verbunden. Diese Funktion ist bei einem verbundenen Socket nicht zulässig, unabhängig davon, ob der Socket verbindungsorientiert oder verbindungslos ist. | |
Die Verbindung wurde unterbrochen, weil eine Keep-Alive-Aktivität einen Fehler erkannt hat, während der Vorgang ausgeführt wurde. | |
Der Deskriptor ist kein Socket. | |
MSG_OOB angegeben wurde, aber der Socket nicht im Streamformat wie der 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. | |
Socket wurde heruntergefahren; Es ist nicht möglich , LPWSPRecvFrom auf einem Socket auszuführen, nachdem LPWSPShutdownmit der Einstellung auf SD_RECEIVE oder SD_BOTH aufgerufen wurde. | |
**Windows NT:** Überlappende Sockets: Es gibt zu viele ausstehende überlappende E/A-Anforderungen. Nicht überlappte Sockets: Der Socket ist als nicht blockiert gekennzeichnet, und der Empfangsvorgang kann nicht sofort abgeschlossen werden. |
|
Die Nachricht war zu groß, um in den angegebenen Puffer zu passen, und (nur bei unzuverlässigen Protokollen) wurde jeder nachfolgende Teil der Nachricht verworfen, der nicht in den Puffer passte. | |
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. | |
Socket s ist nachrichtenorientiert, und die virtuelle Verbindung wurde von der Remoteseite ordnungsgemäß geschlossen. | |
Ein überlappender Vorgang wurde erfolgreich eingeleitet, und der Abschluss wird zu einem späteren Zeitpunkt angezeigt. | |
Der Überlappungsvorgang wurde aufgrund des Schließens des Sockets abgebrochen. |
Hinweise
Die LPWSPRecvFrom-Funktion wird hauptsächlich für einen verbindungslosen Socket verwendet, der von s angegeben wird. Der Socket darf nicht verbunden sein. Die lokale Adresse des Sockets muss bekannt sein. Dies kann explizit über LPWSPBind oder implizit über LPWSPSendTo oder LPWSPJoinLeaf erfolgen.
Für überlappende Sockets wird diese Funktion verwendet, um einen oder mehrere Puffer zu posten, in denen eingehende Daten platziert werden, sobald sie auf einem (möglicherweise verbundenen) Socket verfügbar werden, nach dem die vom Client angegebene 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 LPWSPGetOverlappedResult abgerufen. Beachten Sie außerdem, dass die Werte, auf die von lpFrom und lpFromlen verwiesen wird, erst aktualisiert werden, wenn die Vervollständigung angegeben ist. Anwendungen dürfen diese Werte erst dann verwenden oder stören, wenn sie aktualisiert wurden. Daher darf der Client keine automatischen Variablen (also stapelbasierte Variablen) für diese Parameter verwenden.
Wenn lpOverlapped und 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. Für den Fall eines blockierenden Sockets, bei dem derzeit keine Daten empfangen und vom Transport gepuffert wurden, wird der Aufruf blockiert, bis Daten gemäß der zugewiesenen Blockierungssemantik für LPWSPRecv empfangen werden.
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 so gepackt, dass keine Löcher entstehen.
Das Array von WSABUF-Strukturen , auf das der lpBuffers-Parameter verweist, ist vorübergehend. Wenn dieser Vorgang überlappend 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 verbindungslosen Sockettypen wird die Adresse, von der die Daten stammen, in den Puffer kopiert, auf den lpFrom verweist. Bei der Eingabe wird der wert, auf den von lpFromlen verwiesen wird, auf die Größe dieses Puffers initialisiert und bei Abschluss geändert, um die tatsächliche Größe der dort gespeicherten Adresse anzugeben.
Wie bereits für überlappende Sockets erwähnt, werden die Parameter lpFrom und lpFromlen erst nach Abschluss der überlappenden E/A aktualisiert. Der Speicher, auf den diese Parameter verweisen, muss daher für den Dienstanbieter verfügbar bleiben und kann nicht im Stapelframe des Windows Sockets SPI-Clients zugeordnet werden. Die Parameter lpFrom und lpFromlen werden für verbindungsorientierte Sockets ignoriert.
Bei Bytestream-Sockets (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.
Bei nachrichtenorientierten Sockets wird eine einzelne eingehende Nachricht bis zur Gesamtgröße der bereitgestellten Puffer in die bereitgestellten Puffer platziert, und die Vervollständigungsanzeige tritt für überlappende Sockets auf. Wenn die Nachricht größer als die bereitgestellten Puffer ist, werden die Puffer mit dem ersten Teil der Nachricht gefüllt. Wenn das MSG_PARTIAL-Feature vom Dienstanbieter unterstützt wird, wird das MSG_PARTIAL-Flag in lpFlags für den Socket festgelegt, und nachfolgende Empfangsvorgänge rufen den Rest der Nachricht ab. Wenn MSG_PARTIAL nicht unterstützt wird, aber das Protokoll zuverlässig ist, generiert LPWSPRecvFrom 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 LPWSPRecvFrom generiert den Fehler WSAEMSGSIZE.
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. |
Bei nachrichtenorientierten Sockets wird das MSG_PARTIAL Bit im lpFlags-Parameter festgelegt, wenn eine Teilnachricht empfangen wird. Wenn eine vollständige Nachricht empfangen wird, wird MSG_PARTIAL in lpFlags gelöscht. Bei verzögerter Fertigstellung wird der Wert, auf den lpFlags verweist, nicht aktualisiert. Wenn der Abschluss angegeben wurde, sollte der SPI-Client von Windows Sockets LPWSPGetOverlappedResult aufrufen und die Flags untersuchen, auf die der lpdwFlags-Parameter verweist.
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 abgerufen, indem der lpdwFlags-Parameter von LPWSPGetOverlappedResult untersucht wird.
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. Ein 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. 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 WPUQueueApc aufgerufen wird. 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 Kunden bereitgestellte 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 vom Client bereitgestellten Funktionsnamen. dwError gibt den Abschluss status für den überlappenden Vorgang an, wie durch lpOverlapped angegeben. cbTransferred 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, jedoch nicht unbedingt in derselben Reihenfolge, in der die überlappenden Vorgänge abgeschlossen werden. Es wird jedoch garantiert, dass die bereitgestellten Puffer in derselben Reihenfolge ausgefüllt werden, 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
Unterstützte Mindestversion (Client) | Windows 2000 Professional [nur Desktop-Apps] |
Unterstützte Mindestversion (Server) | Windows 2000 Server [nur Desktop-Apps] |
Kopfzeile | ws2spi.h |