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 |
---|---|
Debe producirse una llamada WSAStartup correcta antes de usar esta función. | |
Error en el subsistema de red. | |
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. | |
La llamada (bloqueo) se canceló a través de WSACancelBlockingCall. | |
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. | |
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. | |
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. | |
Para un socket de datagrama, este error indica que expiró el tiempo de vida. | |
El descriptor del parámetro s no es un socket. | |
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. | |
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. | |
El socket se marca como no desbloqueado y la operación recvfrom se bloquearía. | |
El mensaje era demasiado grande para caber en el búfer al que apunta el parámetro buf y se truncó. | |
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. | |
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). |
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 |