在进行网络服务器开发时,如果涉及到设计网络通讯协议,那么通常我们需要考虑字节序的问题。
举例说明这个问题:
假设我们需要在server与client之间以二进制的形式传递一个4字节的int值: 0X01020304
进一步假设,server端机器为 little endian,client端机器为big endian,
那么这个int值在server端内在中的字节形式为: 4 3 2 1
在client端的字节序为 big endian,在client端的字节形式为: 1 2 3 4

所以,如果我们不对这个int值进行任何的字节序转换而直接从server端发送到client端,那么client端收到的int值的内在字节形式为: 4 3 2 1 , 也即是16进制: 0X04030201。这个值与server端原本传送的值: 0X01020304 不一致,从而产生发数据错误,而错误的原因就在于在以二进制形式传递数值时没有进行字节序转换。

这里需要说明一点: TCP/IP协议规定网络字节序为 big endian。

在以二进制的形式传输int值时,我们需要在server端和client端都进行对应的字节序转换,具体的做法是:
在server 端先调用 htonl 对这个int值进行转换,然后调用send发送这4个字节;
在client 端先接收这4个字节,然后使用 ntohl 将这4个字节转换为对应的int值。
这里提供一个用于检查机器字节序的函数:

01 //! @brief 判断CPU的字节序
02 /*!
03     little endian 就是将数据的低字节放在内存中的低位
04     big endian 就是将数据的低字节放在内存的高位
05     INTEL和AMD: 为little endian ;
06     TCP/IP 网络字节序均为big endian
07     @return 如果为<b>little endian</b>,返回<b>true</b>;
08             如果为<b>big endian</b>,返回<b>false</b>.
09 */
10 inline static bool CheckMachineEndian( void )
11 {
12     short iValue = 1;
13     //如果为big endian , 则在内存中的二进制形式为: 00000000 000000001;
14     //如果为little endian , 则在内存中的二进制形式为: 00000001 00000000
15     char *pValue = reinterpret_cast< char* >( &iValue );
16     if ( 1 == pValue[ 0 ] )                         //little endian
17     {
18         return true;
19     }
20     else    // 0 == pValue                          //big endian
21     {
22         return false;
23     }
24 }

本站原创文章,转载请注明出处。