recv 函式 (winsock.h)

recv函式會從連接的通訊端或系結的無連線通訊端接收資料。

語法

int 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 參數。 旗標參數的可能值是使用位 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 市集應用程式在 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

WSARecv

WSARecvEx

Winsock 函式

Winsock 參考

recvfrom

select

send

socket