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 套接字转换例程 ntohsntohlhtonshtonl之前,,在将数据传递到存档对象,。 用于进行通信的这些功能的示例与非 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 应用程序。

有关更多信息,请参见:

请参见

概念

在MFC的Windows套接字