本文提供使用 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”一詞是用於顯示於通訊的另一端,因此它會指定接收使用者已收到特定數目的數據封包。 接收者會以類似字串來回復,表示「已傳送」,以顯示在原始寄件人的畫面上。 收到這兩個字串表示已成功通訊。
謹慎
如果您要撰寫 MFC 用戶端程式來與已建立的(非 MFC) 伺服器通訊,請勿透過封存傳送C++物件。 除非伺服器是可以理解您要傳送物件的 MFC 應用程式,否則它將無法接收和反序列化您的物件。 Windows Sockets:Byte Ordering 一文中的範例會顯示此類型的通訊。
如需詳細資訊,請參閱 Windows 套接字規格: htonl、 htons、 ntohl、 ntohs。 此外,如需詳細資訊,請參閱:
另請參閱
MFC 中的 Windows 套接字
CArchive::IsStoring
CArchive::operator <<
CArchive::operator >>
CArchive::Flush
CObject::Serialize