sendto 函式 (winsock.h)
sendto函式會將資料傳送至特定目的地。
語法
int sendto(
[in] SOCKET s,
[in] const char *buf,
[in] int len,
[in] int flags,
[in] const sockaddr *to,
[in] int tolen
);
參數
[in] s
描述項,識別 (可能連線) 通訊端。
[in] buf
緩衝區的指標,其中包含要傳輸的資料。
[in] len
buf參數所指向之資料的長度,以位元組為單位。
[in] flags
一組旗標,指定呼叫的進行方式。
[in] to
sockaddr結構的選擇性指標,其中包含目標通訊端的位址。
[in] tolen
to 參數所 指向之位址的大小,以位元組為單位。
傳回值
如果沒有發生錯誤, sendto 會傳回傳送的位元組總數,可能小於 len所指出的數目。 否則,會傳回SOCKET_ERROR的值,並呼叫 WSAGetLastError來擷取特定的錯誤碼。
錯誤碼 | 意義 |
---|---|
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。 | |
網路子系統失敗。 | |
要求的位址是廣播位址,但未設定適當的旗標。 使用 SO_BROADCAST 參數呼叫 setsockopt ,以允許使用廣播位址。 | |
已指定未知旗標,或為啟用SO_OOBINLINE的通訊端指定MSG_OOB。 | |
封鎖的 Windows Sockets 1.1 呼叫已透過 WSACancelBlockingCall取消。 | |
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。 | |
buf或to參數不是使用者位址空間的一部分,或遭竊的參數太小。 | |
連線已中斷,因為持續運作活動偵測作業正在進行時失敗。 | |
沒有可用的緩衝區空間。 | |
通訊端未 (連線導向通訊端) 。 | |
描述項不是通訊端。 | |
已指定MSG_OOB,但通訊端不是資料流程樣式,例如類型SOCK_STREAM、與此通訊端相關聯的通訊網域不支援 OOB 資料,或通訊端是單向的,而且僅支援接收作業。 | |
通訊端已關閉;在 叫用關機 之後,無法傳送至通訊端上的 sendto ,其方式設定 為 SD_SEND 或 SD_BOTH。 | |
通訊端會標示為非封鎖,而要求的作業會封鎖。 | |
通訊端是訊息導向,而且訊息大於基礎傳輸所支援的最大值。 | |
目前無法從此主機連線到遠端主機。 | |
此虛擬電路由於逾時或其他錯誤而終止。 此通訊端無法再使用,應用程式應予以關閉。 | |
執行硬式或失敗關閉的遠端部分已重設此虛擬電路。 針對 UDP 通訊端,遠端主機無法傳遞先前傳送的 UDP 資料包,並以「無法連線的埠」ICMP 封包回應。 此通訊端無法再使用,應用程式應予以關閉。 | |
遠端位址不是有效的位址,例如ADDR_ANY。 | |
指定之系列中的位址無法用於此通訊端。 | |
需要目的地位址。 | |
此時無法透過此主機連接網路。 | |
已嘗試對無法連接的主機進行通訊端作業。 | |
連線已卸載,因為網路失敗,或因為另一端的系統未通知而關閉。 |
備註
sendto函式可用來在通訊端上寫入傳出資料。 對於訊息導向通訊端,請小心不要超過基礎子網的最大封包大小,您可以使用 getsockopt 來擷取通訊端選項的值SO_MAX_MSG_SIZE。 如果資料太長而無法透過基礎通訊協定傳遞,則會傳回 錯誤 WSAEMSGSIZE ,而且不會傳輸任何資料。
to參數可以是通訊端位址系列中的任何有效位址,包括廣播或任何多播位址。 若要傳送至廣播位址,應用程式必須使用 setockopt 並啟用SO_BROADCAST。 否則, sendto 將會失敗,並出現錯誤碼 WSAEACCES。 針對 TCP/IP,應用程式可以傳送至任何多播位址 (,而不需要成為群組成員) 。
如果通訊端未連接,則 為
getsockname 函式可用來判斷與通訊端相關聯的本機埠號碼,但傳回的 IP 位址會設定為指定通訊協定的萬用字元位址 (例如,INADDR_ANY或 「0.0.0.0」 用於 IPv4,IN6ADDR_ANY_INIT或 「::」 表示 IPv6) 。
成功完成 sendto並不表示已成功傳遞資料。
sendto函式通常用於無連接通訊端,以將資料包傳送至由 to參數識別的特定對等通訊端。 即使無連接通訊端先前已連接到特定位址, to 參數仍會覆寫該特定資料包的目的地位址。 在連線導向通訊端上,會忽略 to 和 tolen 參數,讓 sendto 相當於 send。
範例程式碼
下列範例示範 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;
}
針對使用 IP (第 4 版的通訊端)
若要在僅) SOCK_DGRAM上傳送廣播 (,可以建構 to 參數所指向的位址,以包含 Winsock2.h) 中所定義的特殊 IPv4 位址INADDR_BROADCAST (,以及預期的埠號碼。 如果 to 參數所指向的位址包含INADDR_BROADCAST位址和預定的埠,則廣播將會傳送到該埠的所有介面上。如果廣播應該只在特定介面上傳送,則 to 參數所指向的位址應該包含介面和預定埠的子網廣播位址。 例如,子網屏蔽為 255.255.255.0 的 IPv4 網路位址 192.168.1.0 會使用子網廣播位址 192.168.1.255。
廣播資料包通常無法超過片段可能發生的大小,這表示資料包的資料部分 (排除標頭) 不應超過 512 個位元組。
如果傳輸系統中沒有可用的緩衝區空間來保存要傳輸的資料,除非通訊端已置於非封鎖模式中, 否則 sendto 會封鎖。 在非封鎖、資料流程導向通訊端上,寫入的位元組數目可以介於 1 到要求的長度之間,視用戶端和伺服器系統上的緩衝區可用性而定。 select、WSAAsyncSelect或WSAEventSelect函式可用來判斷何時可以傳送更多資料。
允許呼叫具有len為零的sendto,並將傳回零作為有效值。 如果是訊息導向通訊端,則會傳送零長度傳輸資料包。
flags參數可用來影響函式調用的行為,超出針對相關聯通訊端所指定選項。 此函式的語意取決於通訊端選項和 flags 參數。 後者是使用位 OR 運算子搭配下列任何值來建構。
值 | 意義 |
---|---|
MSG_DONTROUTE | 指定資料不應受限於路由。 Windows Sockets 服務提供者可以選擇忽略此旗標。 |
MSG_OOB | (資料流程樣式通訊端傳送 OOB 資料,例如只SOCK_STREAM) 。 |
Windows Phone 8:Windows Phone 8 和更新版本Windows Phone市集應用程式支援此函式。
Windows 8.1和Windows Server 2012 R2:Windows 市集應用程式支援此功能,Windows 8.1、Windows Server 2012 R2 及更新版本。
規格需求
最低支援的用戶端 | Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式] |
最低支援的伺服器 | Windows Server 2003 [傳統型應用程式 |UWP 應用程式] |
目標平台 | Windows |
標頭 | winsock.h (包含 Winsock2.h) |
程式庫 | Ws2_32.lib |
Dll | Ws2_32.dll |