winsock.h (recvfrom 函式)
recvfrom函式會接收資料包並儲存來源位址。
語法
int recvfrom(
[in] SOCKET s,
[out] char *buf,
[in] int len,
[in] int flags,
[out] sockaddr *from,
[in, out, optional] int *fromlen
);
參數
[in] s
識別系結通訊端的描述項。
[out] buf
傳入資料的緩衝區。
[in] len
buf參數所指向之緩衝區的長度,以位元組為單位。
[in] flags
一組選項,可修改函式呼叫的行為,超出為相關聯通訊端指定的選項。 如需詳細資訊,請參閱下面的。
[out] from
sockaddr結構中緩衝區的選擇性指標,會在傳回時保留來源位址。
[in, out, optional] fromlen
參數所指向緩衝區大小的選擇性指標,以位元組為單位。
傳回值
如果沒有發生錯誤, recvfrom 會傳回收到的位元組數目。 如果連接已正常關閉,則傳回值為零。 否則,會傳回SOCKET_ERROR的值,並呼叫 WSAGetLastError來擷取特定的錯誤碼。
錯誤碼 | 意義 |
---|---|
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。 | |
網路子系統失敗。 | |
buf或from參數所指向的緩衝區不在使用者位址空間中,或fromlen參數太小,無法容納對等位址的來源位址。 | |
(封鎖) 呼叫已透過 WSACancelBlockingCall取消。 | |
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。 | |
通訊端尚未與 系結系結,或已指定未知旗標,或已針對已啟用SO_OOBINLINE的通訊端指定MSG_OOB,或只針對位元組資料流程樣式通訊端指定 (,) len 為零或負數。 | |
通訊端已連接。 不論通訊端是面向連線還是無連線,都不允許此函式與連接通訊端搭配使用。 | |
如果是資料包通訊端,此錯誤表示已超過存留時間。 | |
s參數中的描述項不是通訊端。 | |
已指定MSG_OOB,但通訊端不是資料流程樣式,例如類型SOCK_STREAM、與此通訊端相關聯的通訊網域不支援 OOB 資料,或通訊端是單向的,而且僅支援傳送作業。 | |
通訊端已關閉;在叫用關機之後,無法使用設定為 SD_RECEIVE 或 SD_BOTH,在通訊端上復原。 | |
通訊端會標示為非封鎖, 而 recvfrom 作業會封鎖。 | |
訊息太大而無法放入 buf 參數所指向的緩衝區中,並遭到截斷。 | |
連線已卸載,因為網路失敗,或因為另一端的系統未通知而關閉。 | |
執行硬式或失敗關閉的遠端部分已重設此虛擬電路。 應用程式應該關閉通訊端;無法再使用。 在 UDP-datagram 通訊端上,此錯誤表示先前的傳送作業導致 ICMP 埠無法連線 訊息。 |
備註
recvfrom函式會讀取連線和未連線通訊端上的傳入資料,並擷取資料從中傳送的位址。 此函式通常與無連接通訊端搭配使用。 必須知道通訊端的本機位址。 對於伺服器應用程式,這通常是透過 系結明確完成。 用戶端應用程式不建議使用明確系結。 對於使用此函式的用戶端應用程式,通訊端可以透過 sendto、 WSASendTo或 WSAJoinLeaf隱含地系結至本機位址。
對於串流導向通訊端,例如類型為 SOCK_STREAM 的通訊端, 對 recvfrom 的呼叫會傳回目前可用的資訊量,最多可傳回指定的緩衝區大小。 如果通訊端已設定為內嵌接收 OOB 資料 (通訊端選項SO_OOBINLINE) 且 OOB 資料尚未讀取,則只會傳回 OOB 資料。 應用程式可以使用 ioctlsocket 或 WSAIoctlSIOCATMARK 命令來判斷是否要讀取任何 OOB 資料。 連接導向通訊端會忽略 from 和 fromlen 參數。
針對訊息導向通訊端,資料會從第一個排入佇列的訊息擷取,最多可擷取到指定的緩衝區大小。 如果資料包或訊息大於指定的緩衝區,則緩衝區會填入資料包的第一個部分,而 recvfrom 會產生錯誤 WSAEMSGSIZE。 例如,對於不可靠的通訊協定 (,UDP) 多餘的資料會遺失。 如果收到的封包不包含空) (資料, 則來自 recvfrom 函 式的傳回值為零。
如果 from 參數為非零,且通訊端不是連線導向, (類型SOCK_DGRAM例如) ,則傳送資料的對等網路位址會複製到對應的 sockaddr 結構。 fromlen所指向的值會初始化為此結構的大小,並在傳回時加以修改,以指出儲存在sockaddr結構中之位址的實際大小。
如果通訊端上沒有可用的傳入資料, recvfrom 函式會封鎖並等候資料根據 WSARecv 所定義的封鎖規則來抵達,除非通訊端未封鎖,否則不會設定MSG_PARTIAL旗標。 在此情況下,會傳回 SOCKET_ERROR 的值,並將錯誤碼設定為 WSAEWOULDBLOCK。 select、WSAAsyncSelect或WSAEventSelect可用來判斷何時有更多資料送達。
如果通訊端是面向連線,而且遠端端已正常關閉連線,則 對 recvfrom 的呼叫將會立即完成,並接收零個位元組。 如果連線已重設 recvfrom 將會失敗,並出現 WSAECONNRESET錯誤。
flags參數可用來影響函式調用的行為,超出為相關聯通訊端指定的選項。 此函式的語意取決於通訊端選項和 flags 參數。 後者是使用位 OR 運算子搭配下列任何值來建構。
值 | 意義 |
---|---|
MSG_PEEK | 查看傳入的資料。 資料會複製到緩衝區,但不會從輸入佇列中移除。 |
MSG_OOB | 處理頻外 (OOB) 資料。 |
範例程式碼
下列範例示範 recvfrom 函式的使用。#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 = 0;
WSADATA wsaData;
SOCKET RecvSocket;
struct sockaddr_in RecvAddr;
unsigned short Port = 27015;
char RecvBuf[1024];
int BufLen = 1024;
struct sockaddr_in SenderAddr;
int SenderAddrSize = sizeof (SenderAddr);
//-----------------------------------------------
// 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 receiver socket to receive datagrams
RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (RecvSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Bind the socket to any address and the specified port.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
if (iResult != 0) {
wprintf(L"bind failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Call the recvfrom function to receive datagrams
// on the bound socket.
wprintf(L"Receiving datagrams...\n");
iResult = recvfrom(RecvSocket,
RecvBuf, BufLen, 0, (SOCKADDR *) & SenderAddr, &SenderAddrSize);
if (iResult == SOCKET_ERROR) {
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
}
//-----------------------------------------------
// Close the socket when finished receiving datagrams
wprintf(L"Finished receiving. Closing socket.\n");
iResult = closesocket(RecvSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Clean up and exit.
wprintf(L"Exiting.\n");
WSACleanup();
return 0;
}
Windows Phone 8:Windows Phone Windows Phone 8 和更新版本上的市集應用程式支援此函式。
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 |
另請參閱
意見反應
提交並檢視相關的意見反應