首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Windows Sockets:位元組順序(大小端序)轉換完整指南

     編輯:關於C語言

本文為核心技術三部曲之一(配合 Windows Sockets:阻塞、Windows Sockets:字串轉換),詳細說明異構架構間的位元組順序轉換。使用 CAsyncSocket 需自行處理;使用 CSocket 搭配 CArchive 則由框架自動管理。

大端序與小端序

位元組順序含義典型架構
Big-Endian(大端序)最高位位元組在記憶體低地址(網路標準順序)Motorola 68k、PowerPC、SPARC
Little-Endian(小端序)最高位位元組在記憶體高地址Intel x86、AMD64

何時必須轉換位元組順序

  • 傳遞需由網路層解讀的資訊(連接埠、IP 位址等)。
  • 與非 MFC 服務器通訊,且雙方架構位元組順序不同。

可免除轉換的情況

  • 雙端架構相同,協議約定不交換位元組。
  • 對端為 MFC 應用程式(CArchive 內部已處理)。
  • 擁有對端原始碼,可確認是否需要轉換。
  • 將對端移植為 MFC 應用程式(通常代碼更精簡高效)。

CArchive 與網路標準的順序差異

Windows Sockets 標準化為 Big-Endian(網路位元組順序),提供 htonl/htons/ntohl/ntohs 轉換函式。但 CArchive 採用 Little-Endian,並自動處理轉換細節。使用 MFC 套接字的最佳場景是通訊雙端皆為 MFC。

警告: 與非 MFC 應用通訊時,切勿 透過存檔發送 CObject 衍生物件(含 MFC 內部資訊),對端無法解析。參閱 Windows Sockets:使用帶存檔的套接字 說明。

實戰範例:MFC 客戶端與非 MFC 服務器通訊

假設非 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);
    }
}

Windows Sockets 位元組順序轉換函式

函式功能
ntohs16 位:網路序 → 主機序 (Big-Endian → Little-Endian)
ntohl32 位:網路序 → 主機序 (Big-Endian → Little-Endian)
htons16 位:主機序 → 網路序 (Little-Endian → Big-Endian)
htonl32 位:主機序 → 網路序 (Little-Endian → Big-Endian)

相關參考

  • Platform SDK:Windows Sockets 規格
  • Windows Sockets:使用帶存檔的套接字
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved