本文提供一個使用 CSocket 類別搭配 CArchive 物件進行資料序列化傳輸的完整範例。此範例展示兩個應用程式實例(可運行於同一台或不同電腦)如何透過套接字交換資料:一端發送,另一端接收並回覆確認。每個實例皆可發起交換,並可扮演伺服器或客戶端角色。
以下函式定義於應用程式的視圖類別中,展示雙向序列化邏輯:
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);
// 發送表頭資訊:數值與份數
arData << bValue << nCopies;
for(int c = 0; c < nCopies; c++) {
// 發送資料本體
arData << bValue;
}
strText.Format(_T("Received Packet %d of %d (Value=%d, Copies=%d)"), p, nPackets, (int)bValue, nCopies);
// 發送接收確認字串
arData << strText;
arData.Flush();
// 接收對方回覆
arAck >> strText;
DisplayMessage(strText);
}
} else {
CString strText;
BYTE bCheck;
WORD nCopies;
for(int p = 0; p < nPackets; p++) {
// 接收表頭資訊
arData >> bCheck >> nCopies;
for(int c = 0; c < nCopies; c++) {
// 接收資料並驗證
arData >> bValue;
if (bCheck != bValue) AfxMessageBox(_T("Packet Failure"));
}
// 接收並顯示確認字串
arData >> strText;
DisplayMessage(strText);
strText.Format(_T("Sent Packet %d of %d (Value=%d, Copies=%d)"), p, nPackets, (int)bValue, nCopies);
// 發送回覆確認
arAck << strText;
arAck.Flush();
}
}
}
PacketSerialize 採用 if-else 分支結構,依據 arData 存檔物件的模式(存儲/發送 或 載入/接收)決定執行路徑,這與 MFC 標準 Serialize 函式的設計模式完全一致。函式接收兩個 CArchive 參考:arData 用於實際資料傳輸,arAck 用於確認訊息回傳。
注意: arAck 的操作模式必須與 arData 相反:當 arData 發送時,arAck 接收,反之亦然。
bValue 及傳送份數 nCopies。nCopies 指定次數重複發送 bValue。strText,供接收端顯示。bValue 是否與表頭一致,不符則彈出錯誤訊息。此模型採用「已收到」與「已發送」雙向字串回執機制:接收端顯示發送端傳來的「已收到」訊息,並回傳「已發送」訊息供發送端顯示。雙向確認確保通信雙方皆知曉資料傳輸狀態。
警告: 若開發與非 MFC 服務器通訊的 MFC 客戶端,切勿 透過存檔發送 C++ 物件。除非對方也是 MFC 應用程式且知曉物件型別,否則無法正確反序列化。跨平台通訊請參考 Windows Sockets:位元組順序 中的範例。