Windows 소켓: 바이트 순서 지정
이 문서 및 두 개의 참조 문서에서는 Windows 소켓 프로그래밍의 몇 가지 문제를 설명합니다. 이 문서에서는 바이트 순서를 다룹니다. 다른 문제는 Windows 소켓: 차단 및 Windows 소켓: 문자열 변환 문서에서 다룹니다.
CAsyncSocket 클래스를 사용하거나 파생하는 경우 이러한 문제를 직접 관리해야 합니다. CSocket 클래스를 사용하거나 파생하는 경우 MFC가 이를 관리합니다.
바이트 순서 지정
컴퓨터 아키텍처마다 다른 바이트 주문을 사용하여 데이터를 저장하는 경우가 있습니다. 예를 들어 Intel 기반 컴퓨터는 Macintosh(Motorola) 컴퓨터의 역순으로 데이터를 저장합니다. "little-Endian"이라고 하는 Intel 바이트 순서도 네트워크 표준 "big-Endian" 순서의 반대입니다. 다음 표에서는 이러한 용어를 설명합니다.
Big-and Little-Endian 바이트 순서 지정
바이트 순서 지정 | 의미 |
---|---|
빅엔디안 | 가장 중요한 바이트는 단어의 왼쪽 끝에 있습니다. |
리틀 엔디안 | 가장 중요한 바이트는 단어의 오른쪽 끝에 있습니다. |
일반적으로 네트워크를 통해 보내고 받는 데이터의 바이트 순서 변환에 대해 걱정할 필요는 없지만 바이트 주문을 변환해야 하는 상황이 있습니다.
바이트 주문을 변환해야 하는 경우
다음과 같은 상황에서 바이트 주문을 변환해야 합니다.
다른 컴퓨터로 보내는 데이터와 달리 네트워크에서 해석해야 하는 정보를 전달합니다. 예를 들어 네트워크에서 이해해야 하는 포트와 주소를 전달할 수 있습니다.
통신하는 서버 애플리케이션은 MFC 애플리케이션이 아니며 소스 코드가 없습니다. 두 컴퓨터가 동일한 바이트 순서를 공유하지 않는 경우 바이트 순서 변환이 필요합니다.
바이트 주문을 변환할 필요가 없는 경우
다음과 같은 상황에서 바이트 주문을 변환하는 작업을 방지할 수 있습니다.
양쪽 끝의 컴퓨터는 바이트를 교환하지 않는 것에 동의할 수 있으며 두 컴퓨터 모두 동일한 바이트 순서를 사용합니다.
통신하는 서버는 MFC 애플리케이션입니다.
통신하는 서버에 대한 소스 코드가 있으므로 바이트 주문을 변환해야 하는지 여부를 명시적으로 알 수 있습니다.
서버를 MFC로 이식할 수 있습니다. 이 작업은 매우 쉽게 수행할 수 있으며, 결과는 일반적으로 더 작고 더 빠른 코드입니다.
CAsyncSocket을 사용하여 필요한 바이트 순서 변환을 직접 관리해야 합니다. Windows 소켓은 "big-Endian" 바이트 순서 모델을 표준화하고 이 순서와 다른 순서 간에 변환하는 함수를 제공합니다. 그러나 CSocket에서 사용하는 CArchive는 반대("little-Endian") 순서를 사용하지만 CArchive
바이트 순서 변환의 세부 정보를 처리합니다. 애플리케이션에서 이 표준 순서를 사용하거나 Windows 소켓 바이트 순서 변환 함수를 사용하여 코드를 더 이식 가능하게 만들 수 있습니다.
MFC 소켓을 사용하기에 이상적인 경우는 통신의 양쪽 끝을 작성하는 경우입니다. 양쪽 끝에서 MFC를 사용합니다. FTP 서버와 같이 MFC가 아닌 애플리케이션과 통신하는 애플리케이션을 작성하는 경우 Windows 소켓 변환 루틴 ntohs, ntohl, htons 및 htonl을 사용하여 데이터를 보관 개체에 전달하기 전에 바이트 교환을 직접 관리해야 할 수 있습니다. MFC가 아닌 애플리케이션과 통신하는 데 사용되는 이러한 함수의 예는 이 문서의 뒷부분에 나와 있습니다.
참고 항목
통신의 다른 쪽 끝이 MFC 애플리케이션이 아닌 경우 수신기가 이를 처리할 수 없으므로 보관 파일에서 CObject
파생된 C++ 개체를 스트리밍하지 않아야 합니다. Windows 소켓: 보관 파일과 함께 소켓 사용의 참고 사항을 참조하세요.
바이트 주문에 대한 자세한 내용은 Windows SDK에서 사용할 수 있는 Windows 소켓 사양을 참조하세요.
바이트 순서 변환 예제
다음 예제에서는 보관을 사용하는 개체에 CSocket
대한 serialization 함수를 보여줍니다. 또한 Windows 소켓 API에서 바이트 순서 변환 함수를 사용하는 방법을 보여 줍니다.
이 예제에서는 소스 코드에 액세스할 수 없는 비 MFC 서버 애플리케이션과 통신하는 클라이언트를 작성하는 시나리오를 제공합니다. 이 시나리오에서는 MFC가 아닌 서버가 표준 네트워크 바이트 순서를 사용한다고 가정해야 합니다. 반면, MFC 클라이언트 애플리케이션은 개체가 있는 개체를 CSocket
사용하고 네트워크 표준과 CArchive
반대되는 "little-Endian" 바이트 순서를 사용합니다CArchive
.
통신하려는 비 MFC 서버에 다음과 같이 메시지 패킷에 대해 설정된 프로토콜이 있다고 가정합니다.
struct Message
{
long MagicNumber;
unsigned short Command;
short Param1;
long Param2;
};
MFC 용어에서는 다음과 같이 표현됩니다.
struct Message
{
long m_lMagicNumber;
short m_nCommand;
short m_nParam1;
long m_lParam2;
void Serialize(CArchive &ar);
};
C++ struct
에서는 기본적으로 클래스와 동일합니다. 구조체에는 Message
위에서 선언한 멤버 함수와 같은 멤버 함수가 Serialize
있을 수 있습니다. 멤버 함수는 Serialize
다음과 같을 수 있습니다.
void Message::Serialize(CArchive &ar)
{
if (ar.IsStoring())
{
ar << (DWORD)htonl(m_lMagicNumber);
ar << (WORD)htons(m_nCommand);
ar << (WORD)htons(m_nParam1);
ar << (DWORD)htonl(m_lParam2);
}
else
{
WORD w;
DWORD dw;
ar >> dw;
m_lMagicNumber = ntohl((long)dw);
ar >> w;
m_nCommand = ntohs((short)w);
ar >> w;
m_nParam1 = ntohs((short)w);
ar >> dw;
m_lParam2 = ntohl((long)dw);
}
}
이 예제에서는 한쪽 끝에 있는 MFC가 아닌 서버 애플리케이션의 바이트 순서와 CArchive
다른 쪽 끝의 MFC 클라이언트 애플리케이션에서 사용되는 바이트 순서가 명확하게 일치하지 않으므로 데이터의 바이트 순서 변환을 호출합니다. 이 예제에서는 Windows 소켓에서 제공하는 몇 가지 바이트 순서 변환 함수를 보여 줍니다. 다음 표에서는 이러한 함수에 대해 설명합니다.
Windows 소켓 바이트 순서 변환 함수
함수 | 목적 |
---|---|
ntohs | 16비트 수량을 네트워크 바이트 순서에서 호스트 바이트 순서로 변환합니다(big-Endian에서 little-Endian으로). |
ntohl | 32비트 수량을 네트워크 바이트 순서에서 호스트 바이트 순서로 변환합니다(big-Endian에서 little-Endian으로). |
Htons | 호스트 바이트 순서에서 네트워크 바이트 순서로 16비트 수량을 변환합니다(little-Endian에서 big-Endian으로). |
Htonl | 호스트 바이트 순서에서 네트워크 바이트 순서로 32비트 수량을 변환합니다(little-Endian에서 big-Endian으로). |
이 예제의 또 다른 점은 통신의 다른 쪽 끝에 있는 소켓 애플리케이션이 MFC가 아닌 애플리케이션인 경우 다음과 같은 작업을 수행하지 않아야 한다는 것입니다.
ar << pMsg;
여기서 pMsg
클래스에서 CObject
파생된 C++ 개체에 대한 포인터입니다. 그러면 개체와 연결된 추가 MFC 정보가 전송되고 서버는 MFC 애플리케이션인 경우와 마찬가지로 이를 이해하지 못합니다.
자세한 내용은 다음을 참조하세요.