本文提供了使用 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
成员函数由包含子if
else
句的语句组成。 该函数接收两个 CArchive 引用作为参数: arData 和 arAck。 如果为存储(发送)设置了 arData 存档对象,则 if
分支将执行;否则,如果将 arData 设置为加载(接收),该函数将获取 else
分支。 有关 MFC 中的序列化的详细信息,请参阅 序列化。
注释
arAck 存档对象假定与 arData 相反。 如果 arData 用于发送, 则 arAck 接收,反之则为 true。
对于发送,示例函数循环指定次数,每次生成一些随机数据以进行演示。 应用程序将从某些源(例如文件)获取实际数据。 arData 存档的插入运算符 (<<) 用于发送连续三个数据区块的流:
一个指定数据性质的“标头”(在本例中, bValue 变量的值和将发送的副本数)。
此示例会随机生成这两个项。
数据的指定副本数。
内部
for
循环发送 bValue 指定的次数。接收方向用户显示的名为 strText 的字符串。
对于接收,该函数的工作方式类似,只不过它使用存档的提取运算符 (>>) 从存档中获取数据。 接收应用程序验证它接收的数据,显示最终的“已接收”消息,然后发送回一条消息,指出“已发送”,以便发送应用程序显示。
在此通信模型中,在 strText 变量中发送的消息“Received”一词用于在通信的另一端显示,因此它向接收用户指定已接收特定数量的数据包。 接收方使用类似于“Sent”的字符串进行答复,以便在原始发件人的屏幕上显示。 收到这两个字符串表示已成功通信。
谨慎
如果要编写 MFC 客户端程序以与已建立的(非 MFC)服务器通信,请不要通过存档发送C++对象。 除非服务器是了解要发送的对象类型的 MFC 应用程序,否则它将无法接收和反序列化对象。 Windows 套接字:字节排序文章中的一个示例显示了此类型的通信。
有关详细信息,请参阅 Windows 套接字规范: htonl、 htons、 ntohl、 ntohs。 此外,有关详细信息,请参阅:
另请参阅
MFC 中的 Windows 套接字
CArchive::IsStoring
CArchive::operator <<
CArchive::operator >>
CArchive::Flush
CObject::Serialize