参数指向的地址的大小(以字节为单位)。
如果未发生错误,
sendto
将返回发送的字节总数,这可能小于
len
指示的数字。 否则,将返回SOCKET_ERROR值,并且可以通过调用
WSAGetLastError
来检索特定的错误代码。
sendto
函数用于在套接字上写入传出数据。 对于面向消息的套接字,必须小心不要超过基础子网的最大数据包大小,可以使用
getsockopt
来检索套接字选项的值SO_MAX_MSG_SIZE。 如果数据太长而无法通过基础协议进行原子传递,则会返回错误
WSAEMSGSIZE
,并且不会传输任何数据。
to
参数可以是套接字地址系列中的任何有效地址,包括广播或任何多播地址。 若要发送到广播地址,应用程序必须使用
已启用SO_BROADCAST的 setsockopt
。 否则,
sendto
将失败并显示错误代码
WSAEACCES
。 对于 TCP/IP,应用程序可以发送到任何多播地址 (,而无需成为组成员) 。
注意
如果打开套接字,将进行
setsockopt
调用,然后发出
sendto
调用,Windows 套接字将执行隐式
绑定
函数调用。
如果套接字未绑定,系统会将唯一值分配给本地关联,然后将套接字标记为绑定。 如果套接字已连接,则
使用 getsockname
函数来确定与套接字关联的本地 IP 地址和端口。
如果套接字未连接,则为
getsockname
函数可用于确定与套接字关联的本地端口号,但返回的 IP 地址设置为给定协议 (的通配符地址,例如,IPv4 的INADDR_ANY或“0.0.0.0”或IN6ADDR_ANY_INIT或“:”对于 IPv6) 。
sendto
的成功完成并不表示数据已成功传递。
sendto
函数通常用于无连接套接字,以便将数据报发送到由
参数
标识的特定对等套接字。 即使无连接套接字以前已连接到特定地址,
to
参数也会仅覆盖该特定数据报的目标地址。 在面向连接的套接字上,忽略
to
和
tolen
参数,使
sendto
等效于
发送
。
注意
发出阻止 Winsock 调用(如
sendto
)时,Winsock 可能需要等待网络事件,然后调用才能完成。 在这种情况下,Winsock 会执行可警报的等待,这可以通过异步过程调用 (APC) 在同一线程上计划的异步过程调用中断。 在同一线程上中断持续阻塞 Winsock 调用的 APC 中发出另一个阻止 Winsock 调用将导致未定义的行为,并且永远不会由 Winsock 客户端尝试。
以下示例演示
了 sendto
函数的使用。
#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")
int main()
int iResult;
WSADATA wsaData;
SOCKET SendSocket = INVALID_SOCKET;
sockaddr_in RecvAddr;
unsigned short Port = 27015;
char SendBuf[1024];
int BufLen = 1024;
//----------------------
// 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 sending data
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (SendSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
//---------------------------------------------
// Set up the RecvAddr structure with the IP address of
// the receiver (in this example case "192.168.1.1")
// and the specified port number.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = inet_addr("192.168.1.1");
//---------------------------------------------
// Send a datagram to the receiver
wprintf(L"Sending a datagram to the receiver...\n");
iResult = sendto(SendSocket,
SendBuf, BufLen, 0, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
if (iResult == SOCKET_ERROR) {
wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
closesocket(SendSocket);
WSACleanup();
return 1;
//---------------------------------------------
// When the application is finished sending, close the socket.
wprintf(L"Finished sending. Closing socket.\n");
iResult = closesocket(SendSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error: %d\n", WSAGetLastError());
WSACleanup();
return 1;
//---------------------------------------------
// Clean up and quit.
wprintf(L"Exiting.\n");
WSACleanup();
return 0;
若要仅在) SOCK_DGRAM上发送广播 (,可以构造由 to 参数指向的地址,以包含 Winsock2.h) 中定义的特殊 IPv4 地址INADDR_BROADCAST (,以及预期的端口号。 如果 to 参数指向 的地址包含INADDR_BROADCAST地址和预期端口,则广播将在该端口的所有接口上发送。
如果广播应仅在特定接口上发送,则 由 to 参数指向的地址应包含接口和预期端口的子网广播地址。 例如,子网掩码为 255.255.255.255.0 的 IPv4 网络地址为 192.168.1.255。
广播数据报通常不应超过出现的碎片的大小,这意味着数据报的数据部分(不包括标头)不应超过 512 字节。
如果传输系统中没有可用的缓冲区空间来保存要传输的数据, 则 sendto 将阻止,除非套接字处于非阻止模式。 在非阻塞、面向流的套接字上,写入的字节数可以介于 1 和请求的长度之间,具体取决于客户端和服务器系统上的缓冲区可用性。 选择、WSAAsyncSelect 或 WSAEventSelect 函数可用于确定何时可以发送更多数据。
允许调用 len 为零的 sendto,并将返回零作为有效值。 对于面向消息的套接字,发送零长度传输数据报。
标志参数可用于影响函数调用的行为,这些行为超出了为关联套接字指定的选项。 此函数的语义由套接字选项和 标志 参数确定。 后者使用带下列任何值的按位 OR 运算符构造。
MSG_DONTROUTE
:指定数据不应受到路由的约束。 Windows 套接字服务提供商可以选择忽略此标志。
MSG_OOB
仅) SOCK_STREAM等流式套接字发送 OOB 数据 (。
Windows Phone 8:Windows Phone 8 及更高版本上Windows Phone应用商店应用支持此函数。
Windows 8.1和Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。