다음을 통해 공유


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 절이 있는 if 문으로 else 구성됩니다. 이 함수는 두 개의 CArchive 참조를 매개 변수 로 받습니다. arDataarAck. arData 보관 개체가 저장(전송)if을 위해 설정된 경우 분기가 실행되고, 그렇지 않으면 arData가 로드(수신)하도록 설정된 경우 함수가 분기를 else 사용합니다. MFC의 serialization에 대한 자세한 내용은 Serialization을 참조 하세요.

참고 항목

arAck 보관 개체는 arData와 반대되는 것으로 간주됩니다. arData가 전송용이면 arAck이 수신되고 대화가 true입니다.

보내기의 경우 예제 함수는 데모용으로 임의 데이터를 생성할 때마다 지정된 횟수만큼 반복됩니다. 애플리케이션은 파일과 같은 일부 원본에서 실제 데이터를 가져옵니다. arData 보관 파일의 삽입 연산자(<<)는 세 개의 연속 데이터 청크의 스트림을 보내는 데 사용됩니다.

  • 데이터의 특성을 지정하는 "헤더"입니다(이 경우 bValue 변수의 값 및 전송될 복사본 수).

    이 예제에서는 두 항목이 모두 임의로 생성됩니다.

  • 지정된 데이터 복사본 수입니다.

    내부 for 루프는 지정된 횟수만큼 bValue 를 보냅니다.

  • 수신기가 사용자에게 표시하는 strText라는 문자열입니다.

수신의 경우 함수는 보관 파일의 추출 연산자(>>)를 사용하여 보관 파일에서 데이터를 가져오는 것을 제외하고 유사하게 작동합니다. 수신 애플리케이션은 수신한 데이터를 확인하고, 최종 "받은" 메시지를 표시한 다음, 보내는 애플리케이션이 표시할 "Sent"라는 메시지를 다시 보냅니다.

이 통신 모델에서 strText 변수에서 보낸 메시지인 "Received"라는 단어는 통신의 다른 쪽 끝에 표시되므로 수신 사용자에게 특정 수의 데이터 패킷이 수신되었음을 지정합니다. 수신자는 원래 보낸 사람의 화면에 표시하기 위해 "보낸 사람"이라는 유사한 문자열로 회신합니다. 두 문자열을 모두 수신하면 성공적인 통신이 발생했음을 나타냅니다.

주의

설정된(MFC 이외) 서버와 통신하도록 MFC 클라이언트 프로그램을 작성하는 경우 아카이브를 통해 C++ 개체를 전송하지 마십시오. 서버가 보내려는 개체의 종류를 이해하는 MFC 애플리케이션이 아니면 개체를 수신하고 역직렬화할 수 없습니다. Windows 소켓: 바이트 순서 지정 문서의 예제는 이 형식의 통신을 보여 줍니다.

자세한 내용은 Windows 소켓 사양을 참조하세요. htonl, htons, ntohl, ntohs. 또한 자세한 내용은 다음을 참조하세요.

참고 항목

MFC의 Windows 소켓
CArchive::IsStoring
CArchive::operator <<
CArchive::operator >>
CArchive::Flush
CObject::Serialize