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來擷取特定的錯誤碼。

錯誤碼 意義
WSANOTINITIALISED
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。
WSAENETDOWN
網路子系統失敗。
WSAEFAULT
buffrom參數所指向的緩衝區不在使用者位址空間中,或fromlen參數太小,無法容納對等位址的來源位址。
WSAEINTR
(封鎖) 呼叫已透過 WSACancelBlockingCall取消。
WSAEINPROGRESS
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。
WSAEINVAL
通訊端尚未與 結系結,或已指定未知旗標,或已針對已啟用SO_OOBINLINE的通訊端指定MSG_OOB,或只針對位元組資料流程樣式通訊端指定 (,) len 為零或負數。
WSAEISCONN
通訊端已連接。 不論通訊端是面向連線還是無連線,都不允許此函式與連接通訊端搭配使用。
WSAENETRESET
如果是資料包通訊端,此錯誤表示已超過存留時間。
WSAENOTSOCK
s參數中的描述項不是通訊端。
WSAEOPNOTSUPP
已指定MSG_OOB,但通訊端不是資料流程樣式,例如類型SOCK_STREAM、與此通訊端相關聯的通訊網域不支援 OOB 資料,或通訊端是單向的,而且僅支援傳送作業。
WSAESHUTDOWN
通訊端已關閉;在叫用關機之後,無法使用設定為 SD_RECEIVE 或 SD_BOTH,在通訊端上復原
WSAEWOULDBLOCK
通訊端會標示為非封鎖, 而 recvfrom 作業會封鎖。
WSAEMSGSIZE
訊息太大而無法放入 buf 參數所指向的緩衝區中,並遭到截斷。
WSAETIMEDOUT
連線已卸載,因為網路失敗,或因為另一端的系統未通知而關閉。
WSAECONNRESET
執行硬式或失敗關閉的遠端部分已重設此虛擬電路。 應用程式應該關閉通訊端;無法再使用。 在 UDP-datagram 通訊端上,此錯誤表示先前的傳送作業導致 ICMP 埠無法連線 訊息。

備註

recvfrom函式會讀取連線和未連線通訊端上的傳入資料,並擷取資料從中傳送的位址。 此函式通常與無連接通訊端搭配使用。 必須知道通訊端的本機位址。 對於伺服器應用程式,這通常是透過 系結明確完成。 用戶端應用程式不建議使用明確系結。 對於使用此函式的用戶端應用程式,通訊端可以透過 sendtoWSASendToWSAJoinLeaf隱含地系結至本機位址。

對於串流導向通訊端,例如類型為 SOCK_STREAM 的通訊端, 對 recvfrom 的呼叫會傳回目前可用的資訊量,最多可傳回指定的緩衝區大小。 如果通訊端已設定為內嵌接收 OOB 資料 (通訊端選項SO_OOBINLINE) 且 OOB 資料尚未讀取,則只會傳回 OOB 資料。 應用程式可以使用 ioctlsocketWSAIoctlSIOCATMARK 命令來判斷是否要讀取任何 OOB 資料。 連接導向通訊端會忽略 fromfromlen 參數。

針對訊息導向通訊端,資料會從第一個排入佇列的訊息擷取,最多可擷取到指定的緩衝區大小。 如果資料包或訊息大於指定的緩衝區,則緩衝區會填入資料包的第一個部分,而 recvfrom 會產生錯誤 WSAEMSGSIZE。 例如,對於不可靠的通訊協定 (,UDP) 多餘的資料會遺失。 如果收到的封包不包含空) (資料, 則來自 recvfrom 函 式的傳回值為零。

如果 from 參數為非零,且通訊端不是連線導向, (類型SOCK_DGRAM例如) ,則傳送資料的對等網路位址會複製到對應的 sockaddr 結構。 fromlen所指向的值會初始化為此結構的大小,並在傳回時加以修改,以指出儲存在sockaddr結構中之位址的實際大小。

如果通訊端上沒有可用的傳入資料, recvfrom 函式會封鎖並等候資料根據 WSARecv 所定義的封鎖規則來抵達,除非通訊端未封鎖,否則不會設定MSG_PARTIAL旗標。 在此情況下,會傳回 SOCKET_ERROR 的值,並將錯誤碼設定為 WSAEWOULDBLOCKselectWSAAsyncSelectWSAEventSelect可用來判斷何時有更多資料送達。

如果通訊端是面向連線,而且遠端端已正常關閉連線,則 對 recvfrom 的呼叫將會立即完成,並接收零個位元組。 如果連線已重設 recvfrom 將會失敗,並出現 WSAECONNRESET錯誤。

flags參數可用來影響函式調用的行為,超出為相關聯通訊端指定的選項。 此函式的語意取決於通訊端選項和 flags 參數。 後者是使用位 OR 運算子搭配下列任何值來建構。

意義
MSG_PEEK 查看傳入的資料。 資料會複製到緩衝區,但不會從輸入佇列中移除。
MSG_OOB 處理頻外 (OOB) 資料。
 
注意 發出封鎖的 Winsock 呼叫時,例如 recvfrom,Winsock 可能需要等候網路事件,才能完成呼叫。 在此情況下,Winsock 會執行可警示的等候,而非同步程序呼叫 (APC) 排程在相同執行緒上可能會中斷。 在 APC 內發出另一個封鎖 Winsock 呼叫,中斷相同執行緒上持續封鎖 Winsock 呼叫會導致未定義的行為,而且永遠不會由 Winsock 用戶端嘗試。
 

範例程式碼

下列範例示範 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.1Windows 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

另請參閱

WSAAsyncSelect

WSAEventSelect

Winsock 函式

Winsock 參考

recv

send

sockaddr

socket