Windows Sockets: przykład gniazd korzystających z archiwówWindows Sockets: Example of Sockets Using Archives

W tym artykule przedstawiono przykład użycia klasy CSocket.This article presents an example of using class CSocket. W przykładzie zastosowano CArchive obiekty do serializacji danych za pomocą gniazda.The example employs CArchive objects to serialize data through a socket. Należy zauważyć, że nie jest to Serializacja dokumentu do lub z pliku.Note that this is not document serialization to or from a file.

Poniższy przykład ilustruje sposób użycia archiwum do wysyłania i odbierania danych za pomocą CSocket obiektów.The following example illustrates how you use the archive to send and receive data through CSocket objects. Przykład został zaprojektowany tak, aby dwa wystąpienia aplikacji (na tym samym komputerze lub na różnych komputerach w sieci) wymieniali dane.The example is designed so that two instances of the application (on the same machine or on different machines on the network) exchange data. Jedno wystąpienie wysyła dane, które drugie wystąpienie odbiera i potwierdza.One instance sends data, which the other instance receives and acknowledges. Aplikacja może inicjować wymianę i może działać jako serwer lub jako klient dla innej aplikacji.Either application can initiate an exchange, and either can act as server or as client to the other application. Następująca funkcja jest zdefiniowana w klasie widoku aplikacji:The following function is defined in the application's view class:

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

Najważniejszym elementem tego przykładu jest to, że jego struktura jest równoległa do Serialize funkcji MFC.The most important thing about this example is that its structure parallels that of an MFC Serialize function. PacketSerializeFunkcja członkowska składa się z if instrukcji z else klauzulą.The PacketSerialize member function consists of an if statement with an else clause. Funkcja otrzymuje dwa odwołania CArchive jako parametry: arData i arAck.The function receives two CArchive references as parameters: arData and arAck. Jeśli obiekt archiwum arData jest ustawiony do przechowywania (wysyłania), gałąź jest if wykonywana; w przeciwnym razie, jeśli arData jest ustawiona na potrzeby ładowania (otrzymywanie), funkcja przyjmuje else gałąź.If the arData archive object is set for storing (sending), the if branch executes; otherwise, if arData is set for loading (receiving) the function takes the else branch. Aby uzyskać więcej informacji na temat serializacji w MFC, zobacz serializacji.For more information about serialization in MFC, see Serialization.

Uwaga

Założono, że obiekt archiwum arAck jest przeciwieństwem elementu arData.The arAck archive object is assumed to be the opposite of arData. Jeśli arData jest do wysłania, arAck odbiera i ma wartość true.If arData is for sending, arAck receives, and the converse is true.

W przypadku operacji wysyłania Przykładowa pętla działa przez określoną liczbę razy, za każdym razem, gdy w celach demonstracyjnych są generowane pewne dane losowe.For sending, the example function loops for a specified number of times, each time generating some random data for demonstration purposes. Aplikacja będzie uzyskiwać prawdziwe dane z niektórych źródeł, takich jak plik.Your application would obtain real data from some source, such as a file. Operator wstawiania Archiwum arData () służy << do wysyłania strumienia trzech kolejnych fragmentów danych:The arData archive's insertion operator (<<) is used to send a stream of three consecutive chunks of data:

  • "Nagłówek", który określa charakter danych (w tym przypadku wartość zmiennej bValue oraz liczbę kopii do wysłania).A "header" that specifies the nature of the data (in this case, the value of the bValue variable and how many copies will be sent).

    Oba elementy są generowane losowo dla tego przykładu.Both items are generated randomly for this example.

  • Określona liczba kopii danych.The specified number of copies of the data.

    for Pętla wewnętrzna wysyła bValue określoną liczbę razy.The inner for loop sends bValue the specified number of times.

  • Ciąg o nazwie strText , który odbiorca wyświetla dla użytkownika.A string called strText that the receiver displays to its user.

W przypadku odbioru funkcja działa podobnie, z tą różnicą, że używa operatora wyodrębniania archiwum ( >> ) w celu pobierania danych z archiwum.For receiving, the function operates similarly, except that it uses the archive's extraction operator (>>) to get data from the archive. Aplikacja odbierająca weryfikuje otrzymane dane, wyświetla końcowy komunikat "Received", a następnie odsyła komunikat "wysłano", aby można było wyświetlić aplikację wysyłającą.The receiving application verifies the data it receives, displays the final "Received" message, and then sends back a message that says "Sent" for the sending application to display.

W tym modelu komunikacyjnym słowo "Received", komunikat wysłany w zmiennej strText , jest do wyświetlenia na drugim końcu komunikacji, więc określa użytkownika, że otrzymano określoną liczbę pakietów danych.In this communications model, the word "Received", the message sent in the strText variable, is for display at the other end of the communication, so it specifies to the receiving user that a certain number of packets of data have been received. Odbiorca otrzymuje odpowiedzi o podobnym ciągu "wysłane", aby wyświetlić na ekranie oryginalnego nadawcy.The receiver replies with a similar string that says "Sent", for display on the original sender's screen. Otrzymanie obu ciągów wskazuje, że wystąpiła pomyślna komunikacja.Receipt of both strings indicates that successful communication has occurred.

Przestroga

W przypadku pisania programu klienckiego MFC w celu komunikowania się z ustalonymi serwerami (bez MFC) nie należy wysyłać obiektów C++ za pomocą archiwum.If you are writing an MFC client program to communicate with established (non-MFC) servers, do not send C++ objects through the archive. Chyba że serwer jest aplikacją MFC, która zrozumie rodzaje obiektów, które chcesz wysłać, nie będzie można odbierać i deserializować obiektów.Unless the server is an MFC application that understands the kinds of objects you want to send, it won't be able to receive and deserialize your objects. Przykład w artykule Windows Sockets: porządkowanie bajtów pokazuje komunikację tego typu.An example in the article Windows Sockets: Byte Ordering shows a communication of this type.

Aby uzyskać więcej informacji, zobacz Specyfikacja Windows Sockets: htonl, htons, ntohl, ntohs.For more information, see Windows Sockets Specification: htonl, htons, ntohl, ntohs. Ponadto, aby uzyskać więcej informacji, zobacz:Also, for more information, see:

Zobacz teżSee also

Windows Sockets w MFCWindows Sockets in MFC
CArchive:: isprzechowywanieCArchive::IsStoring
CArchive:: operator <<CArchive::operator <<
CArchive:: operator >>CArchive::operator >>
CArchive:: FlushCArchive::Flush
CObject:: serializowaćCObject::Serialize