本文為核心技術三部曲之一(配合 Windows Sockets:阻塞、Windows Sockets:字串轉換),詳細說明異構架構間的位元組順序轉換。使用 CAsyncSocket 需自行處理;使用 CSocket 搭配 CArchive 則由框架自動管理。
| 位元組順序 | 含義 | 典型架構 |
|---|---|---|
| Big-Endian(大端序) | 最高位位元組在記憶體低地址(網路標準順序) | Motorola 68k、PowerPC、SPARC |
| Little-Endian(小端序) | 最高位位元組在記憶體高地址 | Intel x86、AMD64 |
Windows Sockets 標準化為 Big-Endian(網路位元組順序),提供 htonl/htons/ntohl/ntohs 轉換函式。但 CArchive 採用 Little-Endian,並自動處理轉換細節。使用 MFC 套接字的最佳場景是通訊雙端皆為 MFC。
警告: 與非 MFC 應用通訊時,切勿 透過存檔發送 CObject 衍生物件(含 MFC 內部資訊),對端無法解析。參閱 Windows Sockets:使用帶存檔的套接字 說明。
假設非 MFC 服務器使用標準網路位元組順序,協議結構如下:
struct Message {
long MagicNumber;
unsigned short Command;
short Param1;
long Param2;
};
MFC 端序列化實作:
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);
}
}
| 函式 | 功能 |
|---|---|
| ntohs | 16 位:網路序 → 主機序 (Big-Endian → Little-Endian) |
| ntohl | 32 位:網路序 → 主機序 (Big-Endian → Little-Endian) |
| htons | 16 位:主機序 → 網路序 (Little-Endian → Big-Endian) |
| htonl | 32 位:主機序 → 網路序 (Little-Endian → Big-Endian) |