Windows 套接字:字节排序

本文和两指南手册演示 Windows Sockets 编程的一些问题。 本文包括字节顺序。 文章中介绍的其他问题:Windows Sockets:块Windows Sockets:转换字符串

如果使用或派生自类CAsyncSocket,将需要管理这些问题。 如果使用或派生自类CSocket,MFC 为您管理这些。

字节顺序

不同的机器结构采用不同的字节顺序存储数据。 例如,在 Motorola Macintosh 计算机) (相反的顺序基于 Intel 的计算机存储数据。 Intel Little-Endian 字节顺序,名为“”,也是网络标准“Big-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 服务器使用标准 Web 字节顺序。 相反,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 位数。从网络字节顺序为托管 (字节顺序 Big-Endian 为 little-endian)。

ntohl

转换为 32 位数。从网络字节顺序为托管 (字节顺序 Big-Endian 为 little-endian)。

Htons

转换为 16 位数。从网络字节顺序为托管 (字节顺序大端为小端)。

Htonl

转换为 32 位数。从网络字节顺序为托管 (字节顺序大端为小端)。

此示例在另另一点是,一端通信的套接字应用程序非 MFC 应用程序时,则必须避免执行与下面类似的内容:

ar << pMsg;

其中 pMsg 是指针对从类派生的。. C++ 对象的 CObject。 这是发送额外 MFC 的信息与对象,服务器不能理解,那么,将,如果是 MFC 应用程序。

有关详细信息,请参阅:

请参见

概念

MFC 中的 Windows 套接字