Windows套接字:字节顺序
本文和准则手册在 Windows 套接字编程说明若干问题。 本文包含字节顺序。 在其他文章中的问题包括: Windows 套接字:块 和 Windows 套接字:将字符串。
如果从类 CAsyncSocket使用或派生,将需要管理这些问题。 如果从类 CSocket使用或派生, MFC 为您管理它们。
字节顺序
使用不同的字节序列的其他有时计算机体系结构存储数据。 例如,在 Macintosh (Motorola) 设备相反的顺序基于 Intel 的计算机存储数据。 Intel 字节序列,称为 “little-endian,”也是网络标准 “big-endian”的顺序相反。 下表介绍这些术语。
用和 little-endian 字节顺序
字节顺序 |
含义 |
---|---|
用 Endian |
最高有效字节单词的左端。 |
little-endian |
最高有效字节单词的右边。 |
通常,您不必担心您通过网络发送和接收数据的字节序列转换,但是,必须将字节序列的情况。
当您必须将字节序列
您需要在下列情况下将字节序列:
通过需要通过网络解释的信息,并使用发送到另一台计算机的数据相对。 例如,您可以通过端口和网络地址,必须了解。
您进行通信的服务器应用程序不是 MFC 应用程序 (也不需要具有的源代码)。 例如,如果两个计算机不共享相同字节顺序,这需要字节序列转换。
当您不必将字节序列
您可以避免在下列情况下将字节序列工作:
在两端的计算机可以授予不交换字节,因此,两个计算机都将使用同一字节序列。
传达与您的服务器是 MFC 应用程序。
您将使用的服务器的源代码,因此,您可以显式指示是否必须将字节序列。
可以端口服务器到 MFC。 这非常轻松执行,因此,结果通常是更小,代码较快。
与 CAsyncSocket一起使用,则必须管理所有必需的字节序列转换。 Windows 套接字标准化 “big-endian 字节顺序”模型并提供了此序列和其他之间的转换。 CArchive,但是,您使用 CSocket,使用该计数器 (“little-endian”) 命令,但是, CArchive 负责字节序列转换的详细信息您的。 使用此标准排序在应用程序或使用 Windows 套接字字节序列转换功能,可以使代码更具可迁移性。
理想的情况下使用 MFC 套接字是您编写一种通信的两端:使用 MFC 在两端。 如果您编写与非 MFC 应用程序将通信,例如 FTP 服务器,您的应用程序可能需要管理字节交换使用 Windows 套接字转换例程 ntohs、 ntohl、 htons和 htonl之前,,在将数据传递到存档对象,。 用于进行通信的这些功能的示例与非 MFC 应用程序本文中的后面。
备注
当调整通信的另一端不是 MFC 应用程序时,还必须避免流从 CObject 派生的 C++ 对象添加到存档,因为该接收器无法处理它们。在参见 Windows 套接字:使用套接字与存档的说明。
有关字节顺序的更多信息,请参见 Windows 套接字规范,可用于 Windows SDK。
字节序列转换示例
下面的示例演示使用一个存档的 CSocket 对象的序列化功能。 使用在 Windows 套接字 API,的字节序列转换函数它还说明。
此示例向您编写客户端与非 MFC 服务器应用程序通信您无权访问其源代码的一个方案。 在此方案中,您必须假定,非 MFC 服务器使用标准网络字节序列。 相反, MFC 客户端应用程序使用 CSocket 对象的一 CArchive 对象和 CArchive 使用 “little-endian”字节序列,网络标准的相反值。
假设您计划进行通信的消息数据包的已建立的协议如下所示的非 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 服务器应用程序在一端和用于在另一端, MFC 客户端应用程序的 CArchive 之间广泛的不匹配此示例需要数据字节序列转换。 示例演示 Windows 套接字提供的几个字节序列转换函数。 下表描述了这些功能。
Windows 套接字字节序列转换函数
功能 |
用途 |
---|---|
ntohs |
将网络字节序列的 16 位数。承载字节序列 (用 Endian 为 little-endian)。 |
ntohl |
将网络字节序列的 32 位数。承载字节序列 (用 Endian 为 little-endian)。 |
Htons |
将 16 位数。从宿主字节序列到网络字节序列 (little-endian 对的 Endian)。 |
Htonl |
将 32 位数。从宿主字节序列到网络字节序列 (little-endian 对的 Endian)。 |
另一个点此示例是,当在另一端为对应关系的套接字应用程序是非 MFC 应用程序时,必须避免执行与下面类似的内容:
ar << pMsg;
其中 pMsg 是指向从类派生的 c. C++ 对象 CObject。 这将发送额外的 MFC 信息与对象,并且服务器不了解,,它会,如果它是 MFC 应用程序。
有关更多信息,请参见: