recvfrom 関数 (winsock.h)

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

from パラメーターによって指されるバッファーのサイズ (バイト単位) への省略可能なポインター。

戻り値

エラーが発生しない場合、 recvfrom は受信したバイト数を返します。 接続が正常に閉じられている場合、戻り値は 0 になります。 それ以外の場合は、SOCKET_ERRORの値が返され、 WSAGetLastError を呼び出すことによって特定のエラー コードを取得できます。

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

注釈

recvfrom 関数は、接続されているソケットと接続されていないソケットの両方で受信データを読み取り、データの送信元のアドレスをキャプチャします。 この関数は通常、コネクションレス ソケットで使用されます。 ソケットのローカル アドレスは既知である必要があります。 サーバー アプリケーションの場合、これは通常、 バインドによって明示的に行われます。 クライアント アプリケーションでは、明示的なバインドは推奨されません。 この関数を使用するクライアント アプリケーションの場合、ソケットは sendtoWSASendTo、または WSAJoinLeaf を介してローカル アドレスに暗黙的にバインドされます。

SOCK_STREAM型などのストリーム指向ソケットの場合、 recvfrom の呼び出しは、指定されたバッファーのサイズまで、現在使用可能な情報を返します。 ソケットが OOB データのインライン受信用に構成されていて (ソケット オプション SO_OOBINLINE)、OOB データがまだ未読の場合は、OOB データのみが返されます。 アプリケーションは 、ioctlsocket または WSAIoctlSIOCATMARK コマンドを使用して、それ以上の OOB データを読み取り続けるかどうかを判別できます。 接続指向ソケットの場合、 from パラメーターと fromlen パラメーターは無視されます。

メッセージ指向ソケットの場合、指定されたバッファーのサイズまで、最初のエンキューされたメッセージからデータが抽出されます。 データグラムまたはメッセージが指定されたバッファーより大きい場合、バッファーにはデータグラムの最初の部分が入力され、 recvfrom はエラー WSAEMSGSIZE を生成します。 信頼性の低いプロトコル (UDP など) の場合、余分なデータは失われます。 UDP の場合、受信したパケットにデータ (空) が含まれない場合、 recvfrom 関数関数からの戻り値は 0 です。

from パラメーターが 0 以外で、ソケットが接続指向でない場合 (たとえば、SOCK_DGRAM型)、データを送信したピアのネットワーク アドレスが、対応する sockaddr 構造体にコピーされます。 fromlen が指す値は、この構造体のサイズに初期化され、返されるときに、sockaddr 構造体に格納されているアドレスの実際のサイズを示すように変更されます。

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

ソケットが接続指向で、リモート側が接続を正常にシャットダウンした場合、 recvfrom への呼び出しは直ちに完了し、受信したバイト数は 0 になります。 接続がリセットされている場合、 recvfrom はエラー WSAECONNRESET で失敗します。

flags パラメーターを使用すると、関連付けられたソケットに指定されたオプション以外の関数呼び出しの動作に影響を与えることができます。 この関数のセマンティクスは、ソケット オプションと flags パラメーターによって決まります。 後者は、次のいずれかの値を持つビットごとの OR 演算子を使用して構築されます。

意味
MSG_PEEK 受信データをピークします。 データはバッファーにコピーされますが、入力キューからは削除されません。
MSG_OOB 帯域外 (OOB) データを処理します。
 
メモrecvfrom などのブロッキング Winsock 呼び出しを発行する場合、Winsock は呼び出しを完了する前にネットワーク イベントを待機する必要がある場合があります。 Winsock は、この状況でアラート可能な待機を実行します。この待機は、同じスレッドでスケジュールされた非同期プロシージャ 呼び出し (APC) によって中断される可能性があります。 同じスレッドで進行中の Winsock 呼び出しを中断した APC 内で別のブロック 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 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

WSAEventSelect

Winsock 関数

Winsock リファレンス

Recv

送信

Sockaddr

socket