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 パラメーターが指すバッファーには、受信したこのデータが含まれます。 接続が正常に閉じている場合、戻り値は 0 です。

それ以外の場合は、SOCKET_ERRORの値が返され、 WSAGetLastError を呼び出すことによって特定のエラー コードを取得できます。

エラー コード 意味
WSANOTINITIALIZED
この関数を使用する前に 、WSAStartup 呼び出しが正常に行われる必要があります。
WSAENETDOWN
ネットワーク サブシステムが失敗しました。
WSAEFAULT
buf パラメーターは、ユーザー・アドレス・スペースの有効な部分に完全には含まれていません。
WSAENOTCONN
ソケットは接続されていません。
WSAEINTR
(ブロッキング) 呼び出しは WSACancelBlockingCall を介して取り消されました。
WSAEINPROGRESS
ブロックしている Windows ソケット 1.1 呼び出しが進行中であるか、サービス プロバイダーがコールバック関数を処理しています。
WSAENETRESET
接続指向ソケットの場合、このエラーは、操作の進行中に障害を検出した キープアライブ アクティビティが原因で接続が切断されたことを示します。 データグラム ソケットに関して、このエラーは有効期限が切れたことを示します。
WSAENOTSOCK
記述子はソケットではありません。
WSAEOPNOTSUPP
MSG_OOB指定されましたが、ソケットは、型SOCK_STREAM、OOB データがこのソケットに関連付けられている通信ドメインでサポートされていない、またはソケットが一方向であり、送信操作のみをサポートするなど、ストリーム スタイルではありません。
WSAESHUTDOWN
ソケットがシャットダウンされました。SD_RECEIVEまたはSD_BOTHに設定された方法シャットダウンが呼び出された後、ソケットでを受信することはできません。
WSAEWOULDBLOCK
ソケットは非ブロッキングとしてマークされ、受信操作はブロックされます。
WSAEMSGSIZE
メッセージは大きすぎて指定されたバッファーに収まらず、切り捨てられました。
WSAEINVAL
ソケットが bind でバインドされていないか、不明なフラグが指定されたか、SO_OOBINLINEが有効になっているソケットに対して指定されたMSG_OOB、または (バイト ストリーム ソケットの場合のみ) len が 0 または負の値でした。
WSAECONNABORTED
仮想回線はタイムアウトまたはその他の障害のために切断されました。 ソケットが使用できないため、アプリケーションはソケットを閉じる必要があります。
WSAETIMEDOUT
ネットワーク障害が発生したか、ピア システムが応答できなかったため、接続は切断されました。
WSAECONNRESET
強制終了または中止になる閉じる操作を実行するリモート側によって仮想回線がリセットされました。 ソケットが使用できないため、アプリケーションはソケットを閉じる必要があります。 UDP データグラム ソケットでは、このエラーは、以前の送信操作で ICMP "ポートに到達できません" というメッセージが発生したことを示します。

解説

recv 関数は、接続指向ソケットまたはコネクションレス ソケットで受信データを読み取るために使用されます。 接続指向プロトコルを使用する場合は、 recv を呼び出す前にソケットを接続する必要があります。 コネクションレス プロトコルを使用する場合は、 recv を呼び出す前にソケットをバインドする必要があります。

ソケットのローカル アドレスがわかっている必要があります。 サーバー アプリケーションの場合は、明示的な バインド 関数、または暗黙的な accept 関数または WSAAccept 関数を 使用します。 クライアント アプリケーションでは、明示的なバインドは推奨されません。 クライアント アプリケーションの場合、ソケットは 、connectWSAConnectsendtoWSASendTo、または WSAJoinLeaf を使用して、ローカル アドレスに暗黙的にバインドされます。

接続済みソケットまたはコネクションレス・ソケットの場合、 recv 関数は、受信したメッセージの受け入れ元のアドレスを制限します。 関数は、接続で指定されたリモート アドレスからのみメッセージを返します。 他のアドレスからのメッセージは (サイレントに) 破棄されます。

たとえば、接続指向ソケット (型SOCK_STREAM) の場合、 recv を呼び出すと、指定されたバッファーのサイズまで、現在使用できる量のデータが返されます。 ソケットが OOB データのインライン受信用に構成されており (ソケット オプション SO_OOBINLINE)、OOB データがまだ未読の場合は、OOB データのみが返されます。 アプリケーションでは、 ioctlsocket または WSAIoctlSIOCATMARK コマンドを使用して、それ以上の OOB データを読み取り続けるかどうかを判断できます。

コネクションレス ソケット (type SOCK_DGRAM またはその他のメッセージ指向ソケット) の場合、 接続 関数で指定された宛先アドレスから最初のエンキューされたデータグラム (メッセージ) からデータが抽出されます。

データグラムまたはメッセージが指定されたバッファーより大きい場合、バッファーにはデータグラムの最初の部分が入力され、 recv はエラー WSAEMSGSIZE を生成します。 信頼性の低いプロトコル (UDP など) の場合、過剰なデータは失われます。信頼性の高いプロトコルの場合、十分な大きさのバッファーで recv を呼び出して正常に読み取られるまで、データはサービス プロバイダーによって保持されます。

ソケットで受信データが使用できない場合、 recv 呼び出しはブロックし、ソケットが非ブロッキングでない限り、MSG_PARTIAL フラグが設定されていない WSARecv に対して定義されているブロック規則に従ってデータが到着するのを待機します。 この場合、エラー コードが WSAEWOULDBLOCK に設定された状態で、SOCKET_ERRORの値が返されます。 selectWSAAsyncSelect、または WSAEventSelect 関数を使用して、より多くのデータが到着するタイミングを判断できます。

ソケットが接続指向で、リモート側が接続を正常にシャットダウンし、すべてのデータを受信した場合、受信したバイト数がゼロの 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 で失敗します。 このフラグは、データグラム ソケットまたはメッセージ指向ソケットではサポートされていません。
 
メモrecv などのブロッキング Winsock 呼び出しを発行する場合、Winsock は、呼び出しが完了する前にネットワーク イベントを待機する必要がある場合があります。 Winsock は、この状況でアラート可能な待機を実行します。この待機は、同じスレッドでスケジュールされた非同期プロシージャ 呼び出し (APC) によって中断される可能性があります。 同じスレッドで進行中の Winsock 呼び出しを中断した APC 内で別のブロック 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 8 以降のWindows Phone ストア アプリでサポートされています。

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
ヘッダー winsock.h (Winsock2.h を含む)
Library Ws2_32.lib
[DLL] Ws2_32.dll

関連項目

WSAAsyncSelect

WSARecv

WSARecvEx

Winsock 関数

Winsock リファレンス

recvfrom

select

送信

socket