Condividi tramite


Windows Sockets: esempio di socket che utilizzano archivi

Questo articolo presenta un esempio di uso della classe CSocket. Nell'esempio vengono CArchive impiegati oggetti per serializzare i dati tramite un socket. Si noti che non si tratta di serializzazione di documenti da o verso un file.

Nell'esempio seguente viene illustrato come usare l'archivio per inviare e ricevere dati tramite CSocket oggetti . L'esempio è progettato in modo che due istanze dell'applicazione (nello stesso computer o in computer diversi nella rete) scambiano dati. Un'istanza invia dati, che l'altra istanza riceve e riconosce. L'applicazione può avviare uno scambio e può fungere da server o come client per l'altra applicazione. La funzione seguente è definita nella classe view dell'applicazione:

void PacketSerialize(long nPackets, CArchive &arData, CArchive &arAck)
{
   BYTE bValue = 0;
   WORD nCopies = 0;

   if (arData.IsStoring())
   {
      CString strText;
      errno_t err;
      unsigned int number;

      for (int p = 0; p < nPackets; p++)
      {
         err = rand_s(&number);
         // if (err == 0)...
         bValue = (BYTE)(number % 256);

         err = rand_s(&number);
         // if (err == 0)...
         nCopies = (WORD)(number % 32000);

         // Send header information
         arData << bValue << nCopies;
         for (int c = 0; c < nCopies; c++)
         {
            // Send data
            arData << bValue;
         }

         strText.Format(_T("Sender sent packet %d of %d (Value = %d, Copies = %d)"),
                        p + 1, nPackets, (int)bValue, nCopies);

         // Send receipt string
         arData << strText;
         arData.Flush();

         // Receive acknowledgment
         arAck >> strText;
         // display it
         DisplayMessage(strText);
      }
   }
   else
   {
      CString strText;
      BYTE bCheck;

      for (int p = 0; p < nPackets; p++)
      {
         // Receive header information
         arData >> bCheck >> nCopies;
         for (int c = 0; c < nCopies; c++)
         {
            // Receive data
            arData >> bValue;
            if (bCheck != bValue)
            {
               AfxMessageBox(_T("Packet Failure"));
            }
         }

         // Receive receipt string and display it
         arData >> strText;
         DisplayMessage(strText);

         strText.Format(_T("Recipient received packet %d of %d (Value = %d, Copies = %d)"),
                        p + 1, nPackets, (int)bValue, nCopies);

         // Send acknowledgment
         arAck << strText;
         arAck.Flush();
      }
   }
}

L'aspetto più importante di questo esempio è che la struttura parallela a quella di una funzione MFC Serialize . La PacketSerialize funzione membro è costituita da un'istruzione if con una else clausola . La funzione riceve due riferimenti CArchive come parametri: arData e arAck. Se l'oggetto archivio arData è impostato per l'archiviazione (invio), il if ramo viene eseguito; in caso contrario, se arData è impostato per il caricamento (ricezione) la funzione accetta il else ramo. Per altre informazioni sulla serializzazione in MFC, vedere Serializzazione.

Nota

Si presuppone che l'oggetto archivio arAck sia l'opposto di arData. Se arData è per l'invio, arAck riceve e il contrario è true.

Per l'invio, il ciclo della funzione di esempio per un numero specificato di volte, ogni volta che si generano alcuni dati casuali a scopo dimostrativo. L'applicazione otterrebbe dati reali da un'origine, ad esempio un file. L'operatore di inserimento dell'archivio arData (<<) viene usato per inviare un flusso di tre blocchi consecutivi di dati:

  • "intestazione" che specifica la natura dei dati (in questo caso, il valore della variabile bValue e il numero di copie che verranno inviate).

    Entrambi gli elementi vengono generati in modo casuale per questo esempio.

  • Numero specificato di copie dei dati.

    Il ciclo interno for invia bValue il numero specificato di volte.

  • Stringa denominata strText visualizzata dal ricevitore all'utente.

Per la ricezione, la funzione funziona in modo analogo, ad eccezione del fatto che usa l'operatore di estrazione dell'archivio (>>) per ottenere dati dall'archivio. L'applicazione ricevente verifica i dati ricevuti, visualizza il messaggio "Ricevuto" finale e quindi invia un messaggio che indica "Inviato" per la visualizzazione dell'applicazione di invio.

In questo modello di comunicazione, la parola "Received", il messaggio inviato nella variabile strText , è per la visualizzazione all'altra estremità della comunicazione, quindi specifica all'utente ricevente che è stato ricevuto un determinato numero di pacchetti di dati. Il ricevitore risponde con una stringa simile che indica "Inviato", per la visualizzazione sullo schermo del mittente originale. La ricezione di entrambe le stringhe indica che si è verificata una comunicazione corretta.

Attenzione

Se si scrive un programma MFC client per comunicare con server consolidati (non MFC), non inviare oggetti C++ attraverso l'archivio. A meno che il server non sia un'applicazione MFC che comprenda i tipi di oggetti da inviare, non sarà in grado di ricevere e deserializzare gli oggetti. Un esempio nell'articolo Windows Sockets: Ordinamento byte mostra una comunicazione di questo tipo.

Per altre informazioni, vedere Windows Sockets Specification: htonl, htons, ntohl, ntohs. Per altre informazioni, vedere:

Vedi anche

Windows Sockets in MFC
CArchive::IsStoring
CArchive::operator <<
CArchive::operator >>
CArchive::Flush
CObject::Serialize