LPWSPSEND-Rückruffunktion (ws2spi.h)
Die LPWSPSend-Funktion sendet Daten auf einem verbundenen Socket.
Syntax
LPWSPSEND Lpwspsend;
int Lpwspsend(
[in] SOCKET s,
[in] LPWSABUF lpBuffers,
[in] DWORD dwBufferCount,
[out] LPDWORD lpNumberOfBytesSent,
[in] DWORD dwFlags,
[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] 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. Wenn die LPWSPSend-Funktion für eine Winsock-Anwendung aufgerufen wird, besitzt das System diese Puffer, und die Anwendung greift möglicherweise nicht darauf zu. Datenpuffer, auf die in jeder WSABUF-Struktur verwiesen wird, gehören dem System, und Ihre Anwendung greift möglicherweise während der Lebensdauer des Aufrufs nicht darauf zu.
[in] dwBufferCount
Die Anzahl der WSABUF-Strukturen im lpBuffers-Array .
[out] lpNumberOfBytesSent
Ein Zeiger auf die Anzahl der von diesem Aufruf gesendeten Bytes.
[in] dwFlags
Eine Reihe von Flags, die die Art und Weise angibt, in der der Aufruf erfolgt.
[in] lpOverlapped
Ein Zeiger auf eine WSAOverlapped-Struktur (bei nicht überlappten Sockets ignoriert).
[in] lpCompletionRoutine
Typ: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
Ein Zeiger auf die Vervollständigungsroutine, die aufgerufen wird, wenn der Sendevorgang abgeschlossen wurde (bei nicht überlappten Sockets 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 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 Sendevorgang sofort abgeschlossen wurde, gibt LPWSPSend 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 kein überlappender Vorgang initiiert wurde und keine Vervollständigungsanzeige auftritt.
Fehlercode | Bedeutung |
---|---|
Beim Netzwerksubsystem ist ein Fehler aufgetreten. | |
Die angeforderte Adresse ist eine Broadcastadresse, aber das entsprechende Flag wurde nicht festgelegt. | |
Der Windows Sockets-Aufruf wird blockiert, oder der Dienstanbieter verarbeitet weiterhin eine Rückruffunktion. | |
Der lpBuffers-Parameter ist nicht vollständig in einem gültigen Teil des Benutzeradressraums enthalten. | |
Die Verbindung wurde aufgrund des Zurücksetzens des Remotehosts unterbrochen. | |
Die Verbindung wurde unterbrochen, weil eine Keep-Alive-Aktivität einen Fehler erkannt hat, während der Vorgang ausgeführt wurde. | |
„Socket ist nicht verbunden.“ | |
Der Deskriptor ist kein Socket. | |
MSG_OOB angegeben wurde, aber der Socket kein Streamformat aufweist, z. B. typ SOCK_STREAM, werden OOB-Daten in der diesem Socket zugeordneten Kommunikationsdomäne nicht unterstützt, MSG_PARTIAL wird nicht unterstützt, oder der Socket ist unidirektional und unterstützt nur Empfangsvorgänge. | |
Socket wurde heruntergefahren; Es ist nicht möglich , LPWSPSend auf einem Socket zu verwenden, nachdem LPWSPShutdown mit der Einstellung auf SD_SEND 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 Sendevorgang kann nicht sofort abgeschlossen werden. | |
Der Socket ist nachrichtenorientiert, und die Nachricht ist größer als das maximum, das vom zugrunde liegenden Transport unterstützt wird. | |
Der Socket wurde nicht an LPWSPBind gebunden, oder der Socket wird nicht mit dem überlappenden Flag erstellt. | |
Die virtuelle Verbindung wurde aufgrund eines Timeouts oder eines anderen Fehlers beendet. | |
Die virtuelle Verbindung wurde von der Remoteseite zurückgesetzt. | |
Der Überlappungsvorgang wurde aufgrund des Schließens des Sockets oder der Ausführung des Befehls SIO_FLUSH in LPWSPIoctl abgebrochen. |
Hinweise
Die LPWSPSend-Funktion wird verwendet, um ausgehende Daten aus einem oder mehreren Puffern auf einen verbindungsorientierten Socket zu schreiben, der von s angegeben wird. Es kann jedoch auch für verbindungslose Sockets verwendet werden, die über eine festgelegte Standard-Peeradresse verfügen, die über die LPWSPConnect-Funktion eingerichtet wurde.
Bei überlappenden Sockets (erstellt mit LPWSPSocket mit Flag WSA_FLAG_OVERLAPPED) erfolgt dies mithilfe von überlappenden E/A-Vorgängen, es sei denn, sowohl lpOverlapped als auch lpCompletionRoutine sind NULL. In diesem Fall wird der Socket als nicht überlappter Socket behandelt. Eine Vervollständigungsanzeige tritt auf (Aufruf der Vervollständigungsroutine oder Einstellung eines Ereignisobjekts), wenn die bereitgestellten Puffer vom Transport verbraucht wurden. Wenn der Vorgang nicht sofort abgeschlossen wird, wird der endgültige Abschluss status über die Vervollständigungsroutine oder LPWSPGetOverlappedResult abgerufen.
Bei nicht überlappten Sockets werden die Parameter lpOverlapped, lpCompletionRoutine und lpThreadId ignoriert, und LPWSPSend übernimmt die reguläre synchrone Semantik. Daten werden aus den bereitgestellten Puffern in den Puffer des Transports kopiert. Wenn der Socket nicht blockierend und streamorientiert ist und nicht genügend Speicherplatz im Puffer des Transports vorhanden ist, wird LPWSPSend zurückgegeben, wobei nur ein Teil der bereitgestellten Puffer verbraucht wurde. Aufgrund derselben Puffersituation und eines blockierenden Sockets blockiert LPWSPSend , bis alle bereitgestellten Pufferinhalte verbraucht wurden.
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, diese WSABUF-Strukturen zu erfassen, bevor von diesem Aufruf zurückgegeben wird. Dadurch können Anwendungen stapelbasierte WSABUF-Arrays erstellen.
Bei nachrichtenorientierten Sockets muss darauf geachtet werden, dass die maximale Nachrichtengröße des zugrunde liegenden Anbieters nicht überschritten wird, die durch Abrufen des Werts der Socketoption SO_MAX_MSG_SIZE abgerufen werden kann. Wenn die Daten zu lang sind, um das zugrunde liegende Protokoll atomar zu durchlaufen, wird der Fehler WSAEMSGSIZE zurückgegeben, und es werden keine Daten übertragen.
Beachten Sie, dass der erfolgreiche Abschluss einer LPWSPSend nicht darauf hindeutet , dass die Daten erfolgreich übermittelt wurden.
dwFlags 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 dwFlags-Parameter bestimmt. Letzteres wird mithilfe des bitweisen OR-Operators mit einem der folgenden Werte erstellt.
Wert | Bedeutung |
---|---|
MSG_DONTROUTE | Gibt an, dass die Daten nicht routingpflichtig sein sollen. Ein Windows Sockets-Dienstanbieter kann dieses Flag ignorieren; |
MSG_OOB | Sendet OOB-Daten (nur Socket im Streamformat, z. B. SOCK_STREAM). |
MSG_PARTIAL | Gibt an, dass lpBuffers nur eine partielle Nachricht enthält. Beachten Sie, dass der Fehlercode WSAEOPNOTSUPP für Nachrichten zurückgegeben wird, die teilweise Nachrichtenübertragungen nicht unterstützen. |
Wenn ein überlappender Vorgang sofort abgeschlossen wird, gibt LPWSPSend den Wert 0 zurück, und der parameter lpNumberOfBytesSent wird mit der Anzahl der gesendeten Bytes aktualisiert. Wenn der überlappende Vorgang erfolgreich initiiert wurde und später abgeschlossen wird, gibt LPWSPSend SOCKET_ERROR zurück und gibt fehlercode WSA_IO_PENDING an. In diesem Fall wird lpNumberOfBytesSent nicht aktualisiert. Wenn der überlappende Vorgang abgeschlossen ist, wird die übertragene Datenmenge entweder über den cbTransferred-Parameter in der Vervollständigungsroutine (sofern angegeben) oder über den lpcbTransfer-Parameter in LPWSPGetOverlappedResult angegeben.
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. So können zeitsensible Datenübertragungen vollständig in einem präventiven 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 das hEvent-Member von lpOverlapped , wenn der überlappende Vorgang abgeschlossen wird, wenn er ein gültiges Ereignisobjekthandle enthält. Der Windows Sockets SPI-Client kann LPWSPGetOverlappedResult verwenden, um das Ereignisobjekt zu warten oder abzufragen.
Wenn lpCompletionRoutine nicht NULL ist, wird der hEvent-Member ignoriert und kann vom Windows Sockets SPI-Client verwendet werden, um Kontextinformationen an die Vervollständigungsroutine zu übergeben. Ein Client, der eine Nicht-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, führt zu unvorhersehbaren Ergebnissen.
Ein Dienstanbieter veranlasst, 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, auch aus einem anderen Kontext als dem Thread und prozess, der zum Initiieren des überlappenden Vorgangs verwendet wurde.
Ein Dienstanbieter sorgt dafür, dass eine Funktion im richtigen Thread ausgeführt wird, indem WPUQueueApc aufgerufen wird. Beachten Sie, dass diese Funktion im Kontext desselben Prozesses (aber nicht unbedingt desselben Threads) aufgerufen werden muss, der zum Initiieren des überlappenden Vorgangs verwendet wurde. Es liegt in der Verantwortung des Dienstanbieters, dafür zu sorgen, dass dieser Prozesskontext aktiv ist, bevor WPUQueueApc aufgerufen wird.
Die WPUQueueApc-Funktion 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 clientspezifische 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 ruft dann die clientspezifische Vervollständigungsroutine auf.
Der Prototyp für die vom Client bereitgestellte Vervollständigungsroutine lautet wie folgt.
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 die Vervollständigung status für den überlappenden Vorgang an, wie durch lpOverlapped angegeben. cbTransferred gibt die Anzahl der gesendeten Bytes an. Derzeit sind keine Flagwerte definiert, und der dwFlags-Wert ist 0. Diese Funktion gibt keinen Wert zurück.
Die Vervollständigungsroutinen können in beliebiger Reihenfolge aufgerufen werden, allerdings nicht unbedingt in der reihenfolge, in der die überlappenden Vorgänge abgeschlossen werden. Der Dienstanbieter garantiert jedoch dem Client, dass gebuchte Puffer in der gleichen Reihenfolge gesendet 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 werden. 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 |