Función recvfrom (winsock2.h)

La función recvfrom recibe un datagrama y almacena la dirección de origen.

Sintaxis

int WSAAPI recvfrom(
  [in]                SOCKET   s,
  [out]               char     *buf,
  [in]                int      len,
  [in]                int      flags,
  [out]               sockaddr *from,
  [in, out, optional] int      *fromlen
);

Parámetros

[in] s

Descriptor que identifica un socket enlazado.

[out] buf

Un búfer para los datos entrantes.

[in] len

Longitud, en bytes, del búfer al que apunta el parámetro buf .

[in] flags

Conjunto de opciones que modifican el comportamiento de la llamada de función más allá de las opciones especificadas para el socket asociado. Consulte los comentarios siguientes para obtener más detalles.

[out] from

Puntero opcional a un búfer en una estructura sockaddr que contendrá la dirección de origen tras la devolución.

[in, out, optional] fromlen

Puntero opcional al tamaño, en bytes, del búfer al que apunta el parámetro from .

Valor devuelto

Si no se produce ningún error, recvfrom devuelve el número de bytes recibidos. Si la conexión se ha cerrado correctamente, el valor devuelto es cero. De lo contrario, se devuelve un valor de SOCKET_ERROR y se puede recuperar un código de error específico llamando a WSAGetLastError.

Código de error Significado
WSANOTINITIALISED
Debe producirse una llamada de WSAStartup correcta antes de usar esta función.
WSAENETDOWN
Error en el subsistema de red.
WSAEFAULT
El búfer al que apunta la buf o de los parámetros no está en el espacio de direcciones del usuario, o el parámetro fromlen es demasiado pequeño para dar cabida a la dirección de origen de la dirección del mismo nivel.
WSAEINTR
La llamada (bloqueo) se canceló a través de WSACancelBlockingCall.
WSAEINPROGRESS
Una llamada de Bloqueo de Windows Sockets 1.1 está en curso o el proveedor de servicios sigue procesando una función de devolución de llamada.
WSAEINVAL
El socket no se ha enlazado con el enlace o se especificó una marca desconocida, o MSG_OOB se especificó para un socket con SO_OOBINLINE habilitado, o (solo para sockets de estilo de secuencia de bytes) len era cero o negativo.
WSAEISCONN
El socket está conectado. Esta función no se permite con un socket conectado, ya sea que el socket esté orientado a la conexión o sin conexión.
WSAENETRESET
Para un socket de datagrama, este error indica que expiró el tiempo de vida.
WSAENOTSOCK
El descriptor del parámetro s no es un socket.
WSAEOPNOTSUPP
MSG_OOB se especificó, pero el socket no es de estilo de flujo, como el tipo SOCK_STREAM, los datos OOB no se admiten en el dominio de comunicación asociado a este socket o el socket es unidireccional y solo admite operaciones de envío.
WSAESHUTDOWN
El socket se ha apagado; no es posible volver a cargar en un socket después de que se haya invocado el apagado con cómo se establece en SD_RECEIVE o SD_BOTH.
WSAEWOULDBLOCK
El socket se marca como no desbloqueado y la operación recvfrom se bloquearía.
WSAEMSGSIZE
El mensaje era demasiado grande para caber en el búfer al que apunta el parámetro buf y se truncaba.
WSAETIMEDOUT
Se ha quitado la conexión, debido a un error de red o porque el sistema en el otro extremo se ha inactivo sin previo aviso.
WSAECONNRESET
El lado remoto que ejecuta un cierre firme o de anulación restableció el circuito virtual. La aplicación debe cerrar el socket; ya no es utilizable. En un socket UDP-datagram, este error indica que una operación de envío anterior produjo un mensaje inaccesible del puerto ICMP.

Comentarios

La función recvfrom lee los datos entrantes en sockets conectados y no conectados y captura la dirección desde la que se enviaron los datos. Esta función se usa normalmente con sockets sin conexión. La dirección local del socket debe conocerse. En el caso de las aplicaciones de servidor, normalmente esto se realiza explícitamente a través del enlace. No se recomienda el enlace explícito para las aplicaciones cliente. En el caso de las aplicaciones cliente que usan esta función, el socket se puede enlazar implícitamente a una dirección local a través de sendto, WSASendTo o WSAJoinLeaf.

En el caso de los sockets orientados a flujos, como los de tipo SOCK_STREAM, una llamada a recvfrom devuelve tanta información como está disponible actualmente, hasta el tamaño del búfer especificado. Si el socket se ha configurado para la recepción insertada de datos OOB (opción de socket SO_OOBINLINE) y los datos de OOB aún no son leídos, solo se devolverán los datos de OOB. La aplicación puede usar el comando ioctlsocket o WSAIoctlSIOCATMARK para determinar si se van a leer más datos OOB. Los parámetros from y fromlen se omiten para los sockets orientados a la conexión.

En el caso de los sockets orientados a mensajes, los datos se extraen del primer mensaje en cola, hasta el tamaño del búfer especificado. Si el datagrama o mensaje es mayor que el búfer especificado, el búfer se rellena con la primera parte del datagrama y recvfrom genera el error WSAEMSGSIZE. En el caso de los protocolos no confiables (por ejemplo, UDP), se pierden los datos excesivos. Para UDP si el paquete recibido no contiene datos (vacíos), el valor devuelto de la función recvfrom es cero.

Si el parámetro from es distinto de cero y el socket no está orientado a la conexión(tipo SOCK_DGRAM por ejemplo), la dirección de red del mismo nivel que envió los datos se copia en la estructura sockaddr correspondiente. El valor al que apunta fromlen se inicializa en el tamaño de esta estructura y se modifica, de vuelta, para indicar el tamaño real de la dirección almacenada en la estructura sockaddr .

Si no hay datos entrantes disponibles en el socket, la función recvfrom bloquea y espera a que los datos lleguen según las reglas de bloqueo definidas para WSARecv con la marca de MSG_PARTIAL no establecida a menos que el socket no esté desbloqueado. En este caso, se devuelve un valor de SOCKET_ERROR con el código de error establecido en WSAEWOULDBLOCK. Se puede usar la selección, WSAAsyncSelect o WSAEventSelect para determinar cuándo llegan más datos.

Si el socket está orientado a la conexión y el lado remoto ha apagado correctamente la conexión, la llamada a recvfrom se completará inmediatamente con cero bytes recibidos. Si se ha restablecido la conexión , se producirá un error WSAECONNRESET.

El parámetro flags se puede usar para influir en el comportamiento de la invocación de función más allá de las opciones especificadas para el socket asociado. La semántica de esta función viene determinada por las opciones de socket y el parámetro flags . Este último se construye mediante el operador OR bit a bit con cualquiera de los valores siguientes.

Valor Significado
MSG_PEEK Observa los datos entrantes. Los datos se copian en el búfer, pero no se quitan de la cola de entrada.
MSG_OOB Procesa datos fuera de banda (OOB).
 
Nota Al emitir una llamada de Winsock de bloqueo como recvfrom, Winsock puede que tenga que esperar un evento de red antes de que se pueda completar la llamada. Winsock realiza una espera alertable en esta situación, que se puede interrumpir mediante una llamada de procedimiento asincrónica (APC) programada en el mismo subproceso. La emisión de otra llamada winsock de bloqueo dentro de un APC que interrumpió una llamada de Winsock de bloqueo en curso en el mismo subproceso provocará un comportamiento indefinido y los clientes winsock nunca deben intentarlo.
 

Código de ejemplo

En el ejemplo siguiente se muestra el uso de la función 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;
    sockaddr_in RecvAddr;

    unsigned short Port = 27015;

    char RecvBuf[1024];
    int BufLen = 1024;

    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: esta función es compatible con las aplicaciones de Windows Phone Store en Windows Phone 8 y versiones posteriores.

Windows 8.1 y Windows Server 2012 R2: esta función es compatible con las aplicaciones de la Tienda Windows en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.

Requisitos

Requisito Value
Cliente mínimo compatible Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP]
Servidor mínimo compatible Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP]
Plataforma de destino Windows
Encabezado winsock2.h (incluya Winsock2.h)
Library Ws2_32.lib
Archivo DLL Ws2_32.dll

Consulte también

WSAAsyncSelect

WSAEventSelect

Funciones winsock

Referencia de Winsock

recv

enviar

sockaddr

socket