Invio e ricezione di dati PGM
L'invio e la ricezione dei dati PGM sono simili all'invio o alla ricezione di dati in qualsiasi socket. Esistono considerazioni specifiche per PGM, descritte nei paragrafi seguenti.
Invio di dati PGM
Dopo aver creato una sessione del mittente PGM, i dati vengono inviati usando le varie funzioni di invio di Windows Sockets: sendto, sendto, WSASend e WSASendTo. Poiché gli handle di Windows Socket sono handle di file system, altre funzioni, ad esempio WriteFile e CRT, possono anche trasmettere dati. Il frammento di codice seguente illustra un'operazione del mittente PGM:
LONG error;
//:
error = send (s, pSendBuffer, SendLength, 0);
if (error == SOCKET_ERROR)
{
fprintf (stderr, "send() failed: Error = %d\n",
WSAGetLastError());
}
Quando si usa la modalità messaggio (SOCK_RDM), ogni chiamata a una funzione di invio genera un messaggio discreto, che a volte non è auspicabile; un'applicazione può voler inviare un messaggio di 2 megabyte con più chiamate da inviare. In tali circostanze, il mittente può impostare l'opzione socket RM_SET_MESSAGE_BOUNDARY per indicare le dimensioni del messaggio che segue.
Se la finestra di invio è completa, non viene accettato un nuovo invio dall'applicazione fino a quando la finestra non è stata avanzata. Il tentativo di invio in un socket non bloccante ha esito negativo con WSAEWOULDBLOCK; un socket di blocco blocca semplicemente fino all'avanzamento della finestra fino al punto in cui i dati richiesti possono essere memorizzati nel buffer e inviati. In I/O sovrapposto, l'operazione non viene completata finché la finestra non avanza abbastanza per soddisfare i nuovi dati.
Ricezione di dati PGM
Dopo aver creato una sessione del ricevitore PGM, i dati vengono ricevuti usando le varie funzioni di ricezione di Windows Socket: recv, recvfrom, WSARecv e WSARecvFrom. Poiché gli handle di Windows Socket sono anche handle di file, le funzioni ReadFile e CRT possono essere usate anche per ricevere i dati della sessione PGM. Il trasporto inoltra i dati fino al ricevitore finché arriva finché i dati sono in sequenza. Il trasporto garantisce che i dati restituiti siano contigui e liberi di duplicati. Il frammento di codice seguente illustra un'operazione di ricezione 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());
}
Quando si usa la modalità messaggio (SOCK_RDM), il trasporto indica quando viene ricevuto un messaggio parziale, con l'errore WSAEMSGSIZE o impostando il flag di MSG_PARTIAL quando viene restituito dalle funzioni WSARecv e WSARecvFrom. Quando l'ultimo frammento del messaggio completo viene restituito al client, l'errore o il flag non è indicato.
Quando la sessione viene terminata correttamente, l'operazione di ricezione ha esito negativo con WSAEDISCON. Quando la perdita di dati si verifica nel trasporto, PGM esegue temporaneamente il buffer dei pacchetti out-of-sequence e tenta di recuperare i dati persi. Se la perdita di dati non è recuperabile, l'operazione di ricezione ha esito negativo con WSAECONNRESET e la sessione viene terminata. La sessione può essere reimpostata a causa di una serie di condizioni, tra cui quanto segue:
- Il ricevitore o la frequenza di connessione in ingresso è troppo lenta per mantenere il ritmo con la velocità dei dati in ingresso.
- Si verifica una perdita eccessiva di dati, probabilmente a causa di condizioni di rete temporanee, ad esempio problemi di routing, instabilità della rete e così via.
- Si verifica un errore non recuperabile nel mittente.
- L'utilizzo eccessivo delle risorse si verifica nel computer locale, ad esempio il superamento del massimo consentito per l'archiviazione del buffer interno o la verifica di una condizione di risorse non aggiornate.
- Si verifica un errore di verifica della coerenza dei dati.
- L'errore in un componente PGM dipende da, ad esempio TCP/IP o Windows Sockets.
Sia i primi che i secondi dell'elenco precedente potrebbero comportare l'esecuzione di buffer eccessivo prima dell'esaurimento delle risorse o prima di spostarsi al di là della finestra del mittente.
Terminazione di una sessione PGM
Il mittente o il ricevitore PGM possono interrompere l'invio o la ricezione dei dati chiamando closesocket. Il ricevitore deve chiamare closesocket sia sul socket in ascolto che sulla ricezione per evitare perdite di gestione. La chiamata all'arresto del mittente prima di chiamare closesocket garantisce l'invio di tutti i dati e garantisce che i dati di ripristino vengano mantenuti fino a quando la finestra di invio non supera l'ultima sequenza di dati, anche se l'applicazione stessa termina.