Compartir a través de


función recvfrom (winsock.h)

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

Sintaxis

int 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 mediante una llamada a WSAGetLastError.

Código de error Significado
WSANOTINITIALISED
Debe producirse una llamada WSAStartup correcta antes de usar esta función.
WSAENETDOWN
Error en el subsistema de red.
WSAEFAULT
El búfer al que apunta el 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 bind, 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, independientemente de si 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 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 truncó.
WSAETIMEDOUT
Se ha quitado la conexión, debido a un error de red o porque el sistema en el otro extremo se ha reducido 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 se puede usar. En un socket udp-datagrama, este error indica que una operación de envío anterior dio como resultado 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, esto normalmente se realiza explícitamente a través del enlace. No se recomienda el enlace explícito para las aplicaciones cliente. Para 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 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 en línea de datos OOB (opción de socket SO_OOBINLINE) y los datos de OOB todavía 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 deben leer más datos de 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 sobrantes. 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 al tamaño de esta estructura y se modifica, a cambio, 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 MSG_PARTIAL no establecida a menos que el socket no se bloquee. En este caso, se devuelve un valor de SOCKET_ERROR con el código de error establecido en WSAEWOULDBLOCK. La selección, WSAAsyncSelect o WSAEventSelect se puede usar para determinar cuándo llegan más datos.

Si el socket está orientado a la conexión y el lado remoto ha cerrado la conexión correctamente, 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 Examina 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;
    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: 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 winsock.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