Windows 通訊端: 位元組的順序
這份文件與兩個的同一系列文件文件將說明在 Windows 通訊端程式設計的幾個問題。 本文涵蓋位元組順序。 其他的問題包含了文件: Windows 通訊端: 封鎖 和 Windows 通訊端: 轉換字串。
如果您使用,或衍生自類別 CAsyncSocket,您必須自行管理這些問題。 如果您使用,或衍生自類別 CSocket,MFC 則會為您管理它們。
位元組的順序
不同的機器架構有時會將使用不同位元組順序的資料儲存。 例如,Intel 架構電腦會將資料儲存在 Macintosh (Motorola) 機器的相反順序。 呼叫"由小到大,"的 Intel 位元組順序也是網路標準 「 大到小 」 順序相反。 下表解釋這些詞彙。
大型-和由小到大位元組順序
位元組的順序 |
意義 |
---|---|
位元組由大到小 |
最大顯著性位元組位於左字尾無關。 |
位元組由小到大 |
最大顯著性位元組位於文字的右端。 |
一般而言,您不需要擔心位元組順序轉換為您傳送和接收的網路上的資料,但情況下,您必須轉換位元組順序。
當您必須轉換位元組順序
您必須轉換位元組順序在下列情況:
您要傳遞至網路,相較於您要傳送給另一台電腦的資料會被所需的資訊。 例如,您可能會通過連接埠和位址,網路必須了解。
您要與其通訊的伺服器應用程式不是 MFC 應用程式 (和您沒有為它的來源程式碼)。 這會呼叫位元組順序轉換如果兩部機器並不會共用相同的位元組順序。
當您不需要轉換位元組順序
您可以避免轉換位元組順序,請在下列情況下的工作:
在兩端的機器可以同意不要交換位元組,而且兩台電腦使用相同的位元組順序。
MFC 應用程式的伺服器的後方。
讓您知道明確是否與否,您必須轉換位元組順序,您有正在通訊,伺服器的原始程式碼。
您可以移植至 MFC 的伺服器。 這是很容易辦到,而且通常會較小、 較快的程式碼產生。
使用 CAsyncSocket,您必須自行管理任何所需的位元組順序轉換。 Windows 通訊端標準化"大到小 」 的位元組順序模型,並提供此順序和其他人之間進行轉換的功能。 CArchive,不過,您用它與 CSocket,會使用相對 ("由小到大 」) 的順序,但CArchive就會自己料理的位元組順序轉換為您詳細資料。 藉由使用此標準的順序,在您的應用程式,或使用 Windows 通訊端的位元組順序轉換函式,您可以讓您的程式碼可移植性。
使用 MFC 通訊端的理想情況是當您撰寫通訊的兩端: 兩端皆使用 MFC。 如果您正在撰寫的應用程式,將會與通訊等 FTP 伺服器上的非 MFC 應用程式,您可能需要管理位元組-交換自己之前,您將資料傳遞至 [封存] 物件中,使用 Windows 通訊端轉換常式 ntohs, ntohl, htons,以及 htonl。 非 MFC 應用程式與通訊中使用這些函式的範例就會出現在本文稍後。
注意事項 |
---|
當另一端的通訊不是 MFC 應用程式時,您也必須避免衍生自 C++ 物件的資料流CObject到您的封存因為接收者無法處理它們。在 [附註,請參閱 Windows 通訊端: 使用通訊端,以保存檔。 |
如需有關位元組順序的詳細資訊,請參閱 Windows 通訊端規格,可用在Windows SDK。
位元組順序轉換範例
下列範例會示範的序列化函式CSocket會使用封存檔的物件。 它也會說明在 Windows 通訊端 API 中使用的位元組順序轉換函式。
本範例將示範的情況下,您撰寫的用戶端,會與您擁有原始程式檔不能存取的非 MFC 伺服器應用程式進行通訊。 在這個案例中,您必須假設非 MFC 伺服器會使用標準的網路位元組順序。 相反地,MFC 用戶端應用程式是使用CArchive物件與CSocket物件,和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 通訊端的位元組順序轉換函式
Function |
用途 |
---|---|
ntohs |
將 16 位元數量從網路位元組順序轉換為主機位元組順序 (大到小位元組由小到大到)。 |
ntohl |
將 32 位元數量從網路位元組順序轉換為主機位元組順序 (大到小位元組由小到大到)。 |
Htons |
將 16 位元數量從主機位元組順序轉換為網路位元組順序 (由小到大以位元組由大到小)。 |
Htonl |
將 32 位元數量從主機位元組順序轉換為網路位元組順序 (由小到大以位元組由大到小)。 |
這個範例中的另一個重點是非 MFC 應用程式通訊端上的應用程式的另一端的通訊時,您必須避免作下列:
ar << pMsg;
其中pMsg是衍生自類別 C++ 物件的指標CObject。 這將會傳送物件與伺服器相關聯的額外 MFC 資訊不了解它,如同它是 MFC 應用程式。
如需詳細資訊,請參閱: