共用方式為


Windows Sockets:使用封存的通訊端範例

本文提供使用 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 Sockets
CArchive::IsStoring
CArchive::operator <<
CArchive::operator >>
CArchive::Flush
CObject::Serialize