send-Funktion (winsock2.h)
Die Send-Funktion sendet Daten auf einem verbundenen Socket.
Syntax
int WSAAPI send(
[in] SOCKET s,
[in] const char *buf,
[in] int len,
[in] int flags
);
Parameter
[in] s
Ein Deskriptor, der einen verbundenen Socket identifiziert.
[in] buf
Ein Zeiger auf einen Puffer, der die zu übertragenden Daten enthält.
[in] len
Die Länge der Daten in Bytes, auf die der buf-Parameter im Puffer verweist.
[in] flags
Ein Satz von Flags, die die Art und Weise angeben, in der der Aufruf erfolgt. Dieser Parameter wird mithilfe des bitweisen OR-Operators mit einem der folgenden Werte erstellt.
Rückgabewert
Wenn kein Fehler auftritt, gibt send die Gesamtzahl der gesendeten Bytes zurück, die kleiner sein kann als die Anzahl, die im len-Parameter gesendet werden soll. 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. | |
Die angeforderte Adresse ist eine Broadcastadresse, aber das entsprechende Flag wurde nicht festgelegt. Rufen Sie setsockopt mit der Option SO_BROADCAST Socket auf, um die Verwendung der Broadcastadresse zu aktivieren. | |
Ein blockierender Windows Sockets 1.1-Aufruf wurde über WSACancelBlockingCall abgebrochen. | |
Ein blockierter Windows Sockets 1.1-Aufruf wird ausgeführt, oder der Dienstanbieter verarbeitet noch eine Rückruffunktion. | |
Der buf-Parameter ist nicht vollständig in einem gültigen Teil des Benutzeradressraums enthalten. | |
Die Verbindung wurde unterbrochen, weil eine Keep-Alive-Aktivität einen Fehler erkannt hat, während der Vorgang ausgeführt wurde. | |
Es ist kein Pufferplatz verfügbar. | |
Der Socket ist nicht verbunden. | |
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 Empfangsvorgänge. | |
Die Steckdose wurde heruntergefahren; Es ist nicht möglich, an einen Socket zu senden, nachdem das Herunterfahren aufgerufen wurde, wobei auf SD_SEND oder SD_BOTH festgelegt ist. | |
Der Socket wird als nicht blockiert markiert, und der angeforderte Vorgang würde blockiert. | |
Der Socket ist nachrichtenorientiert, und die Nachricht ist größer als das maximum, das vom zugrunde liegenden Transport unterstützt wird. | |
Der Remotehost kann derzeit nicht von diesem Host aus erreicht werden. | |
Der Socket wurde nicht mit bind gebunden, oder es wurde ein unbekanntes Flag angegeben, oder für einen Socket mit aktiviertem SO_OOBINLINE wurde MSG_OOB angegeben. | |
Timeout- oder anderer Fehler. Die virtuelle Verbindung wurde beendet. Die Anwendung sollte den Socket schließen, weil er nicht mehr verwendbar ist. | |
Die virtuelle Verbindung wurde von der Remoteseite zurückgesetzt, die einen harten oder abbrechenden Schließvorgang ausgeführt hat. Bei UDP-Sockets konnte der Remotehost kein zuvor gesendetes UDP-Datagramm übermitteln und antwortete mit einem ICMP-Paket "Port unreachable". Die Anwendung sollte den Socket schließen, weil er nicht mehr verwendbar ist. | |
Die Verbindung wurde aufgrund eines Netzwerkfehlers oder des Ausfalls des Systems am anderen Ende ohne Vorheriges unterbrochen. |
Hinweise
Die Send-Funktion wird verwendet, um ausgehende Daten in einen verbundenen Socket zu schreiben.
Bei nachrichtenorientierten Sockets (Adressfamilie von AF_INET oder AF_INET6, Typ der SOCK_DGRAM und Protokoll von IPPROTO_UDP z. B.) muss darauf geachtet werden, dass die maximale Paketgröße des zugrunde liegenden Anbieters nicht überschritten wird. Die maximale Nachrichtenpaketgröße für einen Anbieter kann durch Aufrufen von getsockopt abgerufen werden, wobei der Parameter optname auf SO_MAX_MSG_SIZE festgelegt ist, um den Wert der Socketoption abzurufen. Wenn die Daten zu lang sind, um sie atomar über das zugrunde liegende Protokoll zu übergeben, wird der Fehler WSAEMSGSIZE zurückgegeben, und es werden keine Daten übertragen.
Der erfolgreiche Abschluss einer Sendefunktion gibt nicht an, dass die Daten erfolgreich an den Empfänger übermittelt und empfangen wurden. Diese Funktion gibt nur an, dass die Daten erfolgreich gesendet wurden.
Wenn im Transportsystem kein Pufferspeicher zur Verfügung steht, um die zu übertragenden Daten aufzunehmen, wird send blockiert, es sei denn, der Socket wurde in den Nichtblockierungsmodus versetzt. Bei nicht blockierenden datenstromorientierten Sockets kann die Anzahl der geschriebenen Bytes zwischen 1 und der angeforderten Länge betragen, abhängig von der Pufferverfügbarkeit auf den Client- und Servercomputern. Die Funktionen select, WSAAsyncSelect oder WSAEventSelect können verwendet werden, um zu bestimmen, wann mehr Daten gesendet werden können.
Das Aufrufen von send mit dem len-Parameter null ist zulässig und wird von Implementierungen als erfolgreich behandelt. In solchen Fällen gibt send null als gültigen Wert zurück. Für nachrichtenorientierte Sockets wird ein Transportdatengramm der Länge Null gesendet.
Der Flags-Parameter kann verwendet werden, um das Verhalten der Funktion über die für den zugeordneten Socket angegebenen Optionen hinaus zu beeinflussen. Die Semantik der Send-Funktion wird durch alle Optionen bestimmt, die zuvor für den Socket festgelegt wurden, der im s-Parameter und im flags-Parameter festgelegt wurde, der an die send-Funktion übergeben wurde.
Die Reihenfolge der zu sendenden Aufrufe ist auch die Reihenfolge, in der die Puffer an die Transportschicht übertragen werden. Send sollte nicht gleichzeitig auf demselben streamorientierten Socket von verschiedenen Threads aufgerufen werden, da einige Winsock-Anbieter eine große Sendeanforderung in mehrere Übertragungen aufteilen können. Dies kann dazu führen, dass unbeabsichtigte Daten aus mehreren gleichzeitigen Sendeanforderungen auf demselben streamorientierten Socket überlappen.
Beispielcode
Im folgenden Beispiel wird die Verwendung der send-Funktion veranschaulicht.#ifndef UNICODE
#define UNICODE
#endif
#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 main() {
//----------------------
// Declare and initialize variables.
int iResult;
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct sockaddr_in clientService;
int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "Client: sending data test";
char recvbuf[DEFAULT_BUFLEN] = "";
//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error: %d\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %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( DEFAULT_PORT );
//----------------------
// Connect to server.
iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
if (iResult == SOCKET_ERROR) {
wprintf(L"connect failed with error: %d\n", WSAGetLastError() );
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
//----------------------
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
wprintf(L"send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %d\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
wprintf(L"shutdown failed with error: %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 )
wprintf(L"Bytes received: %d\n", iResult);
else if ( iResult == 0 )
wprintf(L"Connection closed\n");
else
wprintf(L"recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
// close the socket
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"close failed with error: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
WSACleanup();
return 0;
}
Beispielcode
Ein weiteres Beispiel, das die send-Funktion verwendet, finden Sie unter Erste Schritte Mit Winsock.Hinweise zu IrDA-Sockets
- Die Headerdatei Af_irda.h muss explizit eingeschlossen werden.
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.
Anforderungen
Anforderung | Wert |
---|---|
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 | winsock2.h |
Bibliothek | Ws2_32.lib |
DLL | Ws2_32.dll |