Envío y recepción de datos PGM

El envío y recepción de datos PGM es similar al envío o recepción de datos en cualquier socket. Hay consideraciones específicas para PGM, que se describen en los párrafos siguientes.

Envío de datos PGM

Una vez creada una sesión de remitente de PGM, los datos se envían mediante las distintas funciones de envío de Windows Sockets: send, sendto, WSASend y WSASendTo. Dado que los identificadores de Windows Sockets son identificadores del sistema de archivos, otras funciones como WriteFile y CRT también pueden transmitir datos. En el fragmento de código siguiente se muestra una operación de remitente PGM:

LONG        error;
    //:
error = send (s, pSendBuffer, SendLength, 0);
if (error == SOCKET_ERROR)
{
    fprintf (stderr, "send() failed: Error = %d\n",
             WSAGetLastError());
}

Cuando se usa el modo de mensaje (SOCK_RDM), cada llamada a una función de envío da como resultado un mensaje discreto, que a veces no es deseable; una aplicación puede querer enviar un mensaje de 2 megabytes con varias llamadas para enviar. En tales circunstancias, el remitente puede establecer la opción de socket RM_SET_MESSAGE_BOUNDARY para indicar el tamaño del mensaje que sigue.

Si la ventana de envío está llena, no se acepta un nuevo envío desde la aplicación hasta que se haya avanzado la ventana. Se produce un error al intentar enviar en un socket sin bloqueo con WSAEWOULDBLOCK; un socket de bloqueo simplemente se bloquea hasta que la ventana avanza hasta el punto donde se pueden almacenar en búfer y enviar los datos solicitados. En E/S superpuesta, la operación no se completa hasta que la ventana avanza lo suficiente para adaptarse a los nuevos datos.

Recepción de datos PGM

Una vez creada una sesión de receptor PGM, los datos se reciben mediante las distintas funciones de recepción de Windows Sockets: recv, recvfrom, WSARecv y WSARecvFrom. Dado que los identificadores de Windows Sockets también son identificadores de archivo, las funciones ReadFile y CRT también se pueden usar para recibir datos de sesión PGM. El transporte reenvía los datos hasta el receptor a medida que llega siempre que los datos se encuentre en secuencia. El transporte garantiza que los datos devueltos son contiguos y libres de duplicados. El siguiente fragmento de código muestra una operación de recepción de PGM:

LONG        BytesRead;
    //:
BytesRead = recv (sockR, pTestBuffer, MaxBufferSize, 0);
if (BytesRead == 0)
{
    fprintf(stdout, "Session was terminated\n");
}
else if (BytesRead == SOCKET_ERROR)
{
    fprintf(stderr, "recv() failed: Error = %d\n",
            WSAGetLastError());
}

Cuando se usa el modo de mensaje (SOCK_RDM), el transporte indica cuándo se recibe un mensaje parcial, ya sea con el error WSAEMSGSIZE o estableciendo la marca de MSG_PARTIAL al volver de las funciones WSARecv y WSARecvFrom . Cuando se devuelve el último fragmento del mensaje completo al cliente, no se indica el error o la marca.

Cuando la sesión finaliza correctamente, se produce un error en la operación de recepción con WSAEDISCON. Cuando se produce una pérdida de datos en el transporte, PGM almacena temporalmente en búfer los paquetes fuera de secuencia e intenta recuperar los datos perdidos. Si la pérdida de datos no es irrecuperable, se produce un error en la operación de recepción con WSAECONNRESET y se finaliza la sesión. La sesión se puede restablecer debido a una variedad de condiciones, incluidas las siguientes:

  • El receptor o la velocidad de conexión entrante es demasiado lento para mantener el ritmo de la velocidad de datos entrante.
  • Se produce una pérdida excesiva de datos, posiblemente debido a condiciones de red transitorias, como problemas de enrutamiento, inestabilidad de red, etc.
  • Se produce un error irrecuperable en el remitente.
  • El uso excesivo de recursos se produce en el equipo local, como superar el almacenamiento de búfer interno máximo permitido o encontrar una condición fuera de recursos.
  • Se produce un error de comprobación de coherencia de datos.
  • El error en un PGM de componente depende de, como TCP/IP o Windows Sockets.

Tanto los elementos primero como el segundo de la lista anterior podrían dar lugar a que el receptor realice un almacenamiento en búfer excesivo antes de quedarse sin recursos, o antes de pasar más allá de la ventana del remitente.

Terminación de una sesión PGM

El remitente o receptor PGM puede dejar de enviar o recibir datos llamando a closesocket. El receptor debe llamar a closesocket en los sockets de escucha y recepción para evitar fugas de identificadores. Llamar al apagado en el remitente antes de llamar a Closesocket garantiza que se envían todos los datos y garantiza que los datos de reparación se mantienen hasta que la ventana de envío avanza más allá de la última secuencia de datos, incluso si la propia aplicación finaliza.