recv 函式 (winsock2.h)

recv 函式會從連接的套接字或系結的無連接套接字接收數據。

語法

int WSAAPI recv(
  [in]  SOCKET s,
  [out] char   *buf,
  [in]  int    len,
  [in]  int    flags
);

參數

[in] s

識別已連接套接字的描述項。

[out] buf

要接收傳入數據的緩衝區指標。

[in] len

buf 參數所指向之緩衝區的長度,以位元組為單位。

[in] flags

一組旗標,會影響此函式的行為。 請參閱下面的<備註>。 如需此參數可能值的詳細資訊,請參閱一節。

傳回值

如果沒有發生錯誤, recv 會傳回收到的位元組數目,而 buf 參數所指向的緩衝區將包含此接收的數據。 如果連接已正常關閉,則傳回值為零。

否則,會傳回SOCKET_ERROR的值,並呼叫 WSAGetLastError 來擷取特定的錯誤碼。

錯誤碼 意義
WSANOTINITIALISED
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。
WSAENETDOWN
網路子系統失敗。
WSAEFAULT
buf 參數未完全包含在用戶位址空間的有效部分中。
WSAENOTCONN
未連接此通訊端。
WSAEINTR
(封鎖) 呼叫已透過 WSACancelBlockingCall 取消。
WSAEINPROGRESS
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。
WSAENETRESET
針對面向連線的套接字,此錯誤表示連線已因在作業進行時偵測到失敗的 保持運作 活動而中斷。 如果是資料包通訊端,此錯誤表示已超過存留時間。
WSAENOTSOCK
描述項不是套接字。
WSAEOPNOTSUPP
已指定MSG_OOB,但套接字不是數據流樣式,例如類型SOCK_STREAM、與此套接字相關聯的通訊網域不支援 OOB 數據,或套接字是單向的,而且僅支援傳送作業。
WSAESHUTDOWN
套接字已關閉;在 叫用關機 后無法接收套接字上的 , 其方式 設定為 SD_RECEIVE 或 SD_BOTH。
WSAEWOULDBLOCK
套接字會標示為非封鎖,而且接收作業會封鎖。
WSAEMSGSIZE
訊息太大而無法放入指定的緩衝區,且已截斷。
WSAEINVAL
套接字尚未與 結系結,或已指定未知旗標,或已為啟用SO_OOBINLINE的套接字指定MSG_OOB或只針對位元組數據流套接字指定 (,) len 為零或負數。
WSAECONNABORTED
此虛擬電路由於逾時或其他錯誤而終止。 此通訊端無法再使用,應用程式應予以關閉。
WSAETIMEDOUT
因為網路錯誤或因為對等系統無法回應,所以此連接已中斷。
WSAECONNRESET
執行硬式或失敗關閉的遠端部分已重設此虛擬電路。 此通訊端無法再使用,應用程式應予以關閉。 在UDP-datagram套接字上,此錯誤表示先前的傳送作業導致ICMP「無法連線」訊息。

備註

recv 函式可用來讀取連線導向套接字或無連接套接字上的傳入數據。 使用連線導向通訊協定時,必須先連接套接字,才能呼叫 recv。 使用無連線通訊協定時,必須在呼叫 recv 之前系結套接字。

必須知道套接字的本機位址。 對於伺服器應用程式,請使用明確 系結 函式或隱含 接受WSAAccept 函 式。 用戶端應用程式不建議使用明確系結。 針對用戶端應用程式,套接字可以使用 connectWSAConnectsendtoWSASendToWSAJoinLeaf 隱含地系結至本機位址。

針對已連線或無連線的套接字, recv 函式會限制接受接收訊息的位址。 函式只會從連接中指定的遠端位址傳回訊息。 其他地址的訊息 (以無訊息方式) 捨棄。

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

對於無連線套接字 (類型SOCK_DGRAM或其他訊息導向套接字) ,數據會從 連線 函式指定的目的地位址擷取第一個加入佇列的數據報 (訊息) 。

如果數據報或訊息大於指定的緩衝區,則緩衝區會填入數據報的第一個部分,而 recv 會產生錯誤 WSAEMSGSIZE。 例如,對於不可靠的通訊協定 (,UDP) 多餘的數據遺失;對於可靠的通訊協議,數據會由服務提供者保留,直到呼叫具有足夠大緩衝區 的 recv 成功讀取為止。

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

如果套接字是面向連線,而且遠端端已正常關閉連線,而且已收到所有數據, 則 recv 會立即完成,並接收零個字節。 如果連線已重設, recv 將會失敗,並出現 WSAECONNRESET 錯誤。

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

意義
MSG_PEEK 查看傳入的數據。 數據會複製到緩衝區,但不會從輸入佇列中移除。
MSG_OOB 處理頻外 (OOB) 數據。
MSG_WAITALL 只有在發生下列其中一個事件時,接收要求才會完成:
  • 呼叫端提供的緩衝區已完全滿。
  • 此連接已經關閉。
  • 要求已取消或發生錯誤。
請注意,如果基礎傳輸不支援MSG_WAITALL,或套接字處於非封鎖模式,則此呼叫將會因 WSAEOPNOTSUPP 而失敗。 此外,如果已指定MSG_WAITALL以及MSG_OOB、MSG_PEEK或MSG_PARTIAL,則此呼叫將會失敗併產生 WSAEOPNOTSUPP。 數據報套接字或訊息導向套接字不支援此旗標。
 
注意 發出封鎖的 Winsock 呼叫,例如 recv 時,Winsock 可能需要等候網路事件,才能完成呼叫。 在此情況下,Winsock 會執行可警示的等候,而異步過程調用 (APC) 排程在相同線程上可能會中斷。 在 APC 內發出另一個封鎖 Winsock 呼叫,中斷相同線程上持續封鎖 Winsock 呼叫會導致未定義的行為,而且永遠不會由 Winsock 客戶端嘗試。
 

範例程序代碼

下列程式代碼範例示範 recv 函式的使用。
#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 __cdecl main() {

    //----------------------
    // Declare and initialize variables.
    WSADATA wsaData;
    int iResult;

    SOCKET ConnectSocket = INVALID_SOCKET;
    struct sockaddr_in clientService; 

    char *sendbuf = "this is a test";
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
  
    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
      printf("WSAStartup failed: %d\n", iResult);
      return 1;
    }

    //----------------------
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %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( 27015 );

    //----------------------
    // Connect to server.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
    if ( iResult == SOCKET_ERROR) {
        closesocket (ConnectSocket);
        printf("Unable to connect to server: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf("send failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %ld\n", iResult);

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed: %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 )
            printf("Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            printf("Connection closed\n");
        else
            printf("recv failed: %d\n", WSAGetLastError());

    } while( iResult > 0 );

    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}


範例程序代碼

如需詳細資訊,以及 recv 函式的另一個範例,請參閱使用 Winsock 使用者入門

Windows Phone 8:Windows Phone Windows Phone 8 和更新版本上的市集應用程式支援此函式。

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更新版本上的 Windows 市集應用程式支援此函式。

規格需求

需求
最低支援的用戶端 Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 winsock2.h (包含 Winsock2.h)
程式庫 Ws2_32.lib
Dll Ws2_32.dll

另請參閱

WSAAsyncSelect

WSARecv

WSARecvEx

Winsock 函式

Winsock 參考

recvfrom

select

send

socket