Windows Sockets: Example of Sockets Using Archives
| Overview | How Do I | Sample
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.