Dela via


Windows Sockets: Exempel på socketar som använder arkiv

Den här artikeln visar ett exempel på hur du använder CSocket för klassen. Exemplet använder CArchive objekt för att serialisera data via en socket. Observera att detta inte är serialisering av dokument till eller från en fil.

I följande exempel visas hur du använder arkivet för att skicka och ta emot data via CSocket objekt. Exemplet är utformat så att två instanser av programmet (på samma dator eller på olika datorer i nätverket) utbyter data. En instans skickar data, som den andra instansen tar emot och bekräftar. Antingen kan programmet starta ett utbyte och kan antingen fungera som server eller som klient till det andra programmet. Följande funktion definieras i programmets visningsklass:

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();
      }
   }
}

Det viktigaste med det här exemplet är att dess struktur är parallell med en MFC-funktion Serialize . Medlemsfunktionen PacketSerialize består av en if-instruktion med en else-sats. Funktionen tar emot två CArchive-referenser som parametrar: arData och arAck. Om arData-arkivobjektet har angetts för lagring (sändning) körs if-grenen. Annars, om arData har angetts för inläsning (mottagning), tar funktionen else-grenen. Mer information om serialisering i MFC finns i Serialisering.

Anmärkning

arAck-arkivobjektet antas vara motsatsen till arData. Om arData är för att skicka, tar arAck emot, och motsatsen gäller.

För att skicka loopar exempelfunktionen för ett angivet antal gånger, varje gång som vissa slumpmässiga data genereras i demonstrationssyfte. Ditt program skulle hämta verkliga data från en källa, till exempel en fil. arData-arkivets infogningsoperator (<<) används för att skicka en ström med tre på varandra följande datasegment:

  • Ett "huvud" som anger typen av data (i det här fallet värdet för bValue-variabeln och hur många kopior som ska skickas).

    Båda objekten genereras slumpmässigt för det här exemplet.

  • Det angivna antalet kopior av data.

    Den inre for loopen skickar bValue det angivna antalet gånger.

  • En sträng med namnet strText som mottagaren visar för användaren.

För att ta emot fungerar funktionen på samma sätt, förutom att den använder arkivets extraheringsoperator (>>) för att hämta data från arkivet. Det mottagande programmet verifierar de data som det tar emot, visar det slutliga meddelandet "Mottaget" och skickar sedan tillbaka ett meddelande som säger "Skickat" för att det sändande programmet ska visas.

I den här kommunikationsmodellen ska ordet "Received", meddelandet som skickas i variabeln strText , visas i andra änden av kommunikationen, så det anger för den mottagande användaren att ett visst antal datapaket har tagits emot. Mottagaren svarar med en liknande sträng som säger "Skickat" för visning på den ursprungliga avsändarens skärm. Mottagandet av båda strängarna indikerar att det har skett en lyckad kommunikation.

Försiktighet

Om du skriver ett MFC-klientprogram för att kommunicera med etablerade servrar (icke-MFC) ska du inte skicka C++-objekt via arkivet. Om inte servern är ett MFC-program som förstår vilka typer av objekt du vill skicka kan den inte ta emot och deserialisera dina objekt. Ett exempel i artikeln Windows Sockets: Byte Ordering visar en kommunikation av den här typen.

Mer information finns i Windows Sockets Specification: htonl, htons, ntohl, ntohs. Mer information finns också i:

Se även

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