Share via


Windows Sockets: Example of Sockets Using Archives

OverviewHow Do ISample

This article presents an example of using class . The example employs CArchive objects to serialize data via a socket. Note that this is not document serialization to or from a file.

The following example illustrates how you use the archive to send and receive data via CSocket objects. The example is designed so that two instances of the application (on the same machine or on different machines on the network) exchange data. One instance sends data, which the other instance receives and acknowledges. Either application can initiate an exchange — either can act as server or as client to the other application. The following function is defined in the application’s view class:

void CBlabberView::PacketSerialize(long nPackets, CArchive& arData,
                                    CArchive& arAck)
{
    if (arData.IsStoring())
    {
        CString strText;

        for(int p = 0; p < nPackets; p++)
        {
            BYTE bValue = (BYTE)(rand()%256);
            WORD nCopies = (WORD)(rand()%32000);

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

            Text.Format("Received Packet %d of %d 
                (Value=%d,Copies=%d)",p,nPackets,(int)bValue,nCopies);

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

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

        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 (nCheck != bValue)
                    AfxMessageBox("Packet Failure");
            }
        }

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

        Text.Format("Sent Packet %d of %d
            (Value=%d,Copies=%d)",p,nPackets,(int)bValue,nCopies);

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

The most important thing about this example is that its structure parallels that of an MFC Serialize function. The PacketSerialize member function consists of an if statement with an else clause. The function receives two references as parameters: arData and arAck. 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. For more information about serialization in MFC, see the article Serialization.

Note   The arAck archive object is assumed to be the opposite of arData. If arData is for sending, arAck receives, and vice versa.

For sending, the example function loops for a specified number of times, each time generating some random data for demonstration purposes. Your application would obtain real data from some source, such as a file. The arData archive’s insertion operator (<<) is used to send a stream of three consecutive chunks of data:

  • 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).

    Both items are generated randomly for this example.

  • The specified number of copies of the data.

    The inner for loop sends bValue the specified number of times.

  • A string called strText that the receiver displays to its user.

For receiving, the function operates similarly, except that it uses the archive’s extraction operator (>>) to get data from the archive. The receiving application verifies the data it receives, displays the final “Received” message, then sends back a message that says “Sent” for the sending application to display.

Don’t be confused by the word “Received” in the message sent in the strText variable. In this communications model, it’s 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. The receiver replies with a similar string that says “Sent” — for display on the original sender’s screen. Receipt of both strings indicates that successful communication has occurred.

Caution   If you are writing an MFC client program to communicate with established (non-MFC) servers, don’t send C++ objects via the archive. 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. An example in the article Windows Sockets: Byte Ordering shows a communication of this type.

For more information, see Windows Sockets Specification: htonl, htons, ntohl, ntohs.

What do you want to know more about?

See Also   , , , , ,