Windows 套接字:使用存档的套接字的示例
本文演示了使用 CSocket 类的示例。 该示例使用 CArchive
对象通过套接字将数据序列化。 请注意,这不是将文档序列化为文件,也不是将文件序列化为文档。
以下示例说明如何使用存档通过 CSocket
对象发送和接收数据。 该示例旨在使应用程序的两个实例(在同一台计算机上或在网络上的不同计算机上)交换数据。 一个实例发送数据,另一个实例接收并确认该数据。 任何一个应用程序都可以发起交换,并且可充当另一应用程序的服务器或客户端。 以下函数在应用程序的视图类中定义:
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();
}
}
}
此示例最重要的一点是,其结构与 MFC Serialize
函数的结构相似。 PacketSerialize
成员函数由包含 else
子句的 if
语句组成。 该函数接收两个 CArchive 引用作为参数:arData 和 arAck。 如果 arData 存档对象设置为用于存储(发送),则执行 if
分支;如果 arData 设置为用于加载(接收),则函数采用 else
分支。 有关 MFC 中的序列化的详细信息,请参阅序列化。
注意
假设 arAck 存档对象与 arData 相反。 如果 arData 用于发送,arAck 则用于接收,反之亦然。
对于发送,示例函数循环特定次数,每次生成一些随机数据以供演示。 应用程序将从某些来源(如文件)获取真实数据。 arData 存档的插入运算符 (<<) 用于发送三个连续数据块的流:
指定数据性质的“标头”(在本例中,是 bValue 变量的值以及将发送的副本数)。
这两个项都是为本示例随机生成的。
数据的指定副本数。
内部
for
循环发送 bValue 特定次数。接收方向其用户显示名为 strText 的字符串。
对于接收,该函数的操作类似,只是它使用存档的提取运算符 (>>) 从存档中获取数据。 接收应用程序验证其接收的数据,显示最终“已接收”的消息,然后发回一条显示“已发送”的消息,供发送应用程序显示。
在此通信模型中,“已接收”一词(即在 strText 变量中发送的消息)用于在通信的另一端显示,因此,它向接收用户指定已接收到一定数量的数据包。 接收方用类似的字符串回复,上面写着“已发送”,以显示在原始发送方的屏幕上。 收到这两个字符串表明已成功通信。
注意
如果您要编写 MFC 客户端程序来与建立的(非 MFC)服务器通信,则请勿通过存档发送 C++ 对象。 除非服务器是知道你要发送的对象类型的 MFC 应用程序,否则它将无法接收和反序列化对象。 Windows 套接字:字节顺序文章中的一个示例显示了这类通信。
有关详细信息,请参阅 Windows 套接字规范:htonl、htons、ntohl、ntohs。 有关详细信息,另请参阅:
另请参阅
MFC 中的 Windows 套接字
CArchive::IsStoring
CArchive::operator <<
CArchive::operator >>
CArchive::Flush
CObject::Serialize