当前位置 : 主页 > 编程语言 > c语言 >

Thrift 大小端系统字节序传输剖析

来源:互联网 收集:自由互联 发布时间:2023-09-03
说明 libthrift\src\thrift\protocol\TProtocol.h文件宏定义 __THRIFT_BYTE_ORDER定义了当前系统采用大端字节序还是小端字节序进行数据的存储 相关代码 #ifdef HAVE_SYS_PARAM_H#include sys/param.h#endif#ifndef __

说明

libthrift\src\thrift\protocol\TProtocol.h文件宏定义

__THRIFT_BYTE_ORDER定义了当前系统采用大端字节序还是小端字节序进行数据的存储


相关代码

#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif

#ifndef __THRIFT_BYTE_ORDER
# if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
#  define __THRIFT_BYTE_ORDER BYTE_ORDER
#  define __THRIFT_LITTLE_ENDIAN LITTLE_ENDIAN
#  define __THRIFT_BIG_ENDIAN BIG_ENDIAN
# else
#  include <boost/config.hpp>
#  include <boost/detail/endian.hpp>
#  define __THRIFT_BYTE_ORDER BOOST_BYTE_ORDER
#  ifdef BOOST_LITTLE_ENDIAN
#   define __THRIFT_LITTLE_ENDIAN __THRIFT_BYTE_ORDER
#   define __THRIFT_BIG_ENDIAN 0
#  else
#   define __THRIFT_LITTLE_ENDIAN 0
#   define __THRIFT_BIG_ENDIAN __THRIFT_BYTE_ORDER
#  endif
# endif
#endif

#if __THRIFT_BYTE_ORDER == __THRIFT_BIG_ENDIAN
#  define ntohll(n) (n)
#  define htonll(n) (n)
# if defined(__GNUC__) && defined(__GLIBC__)
#  include <byteswap.h>
#  define htolell(n) bswap_64(n)
#  define letohll(n) bswap_64(n)
# else /* GNUC & GLIBC */
#  define bswap_64(n) \
      ( (((n) & 0xff00000000000000ull) >> 56) \
      | (((n) & 0x00ff000000000000ull) >> 40) \
      | (((n) & 0x0000ff0000000000ull) >> 24) \
      | (((n) & 0x000000ff00000000ull) >> 8)  \
      | (((n) & 0x00000000ff000000ull) << 8)  \
      | (((n) & 0x0000000000ff0000ull) << 24) \
      | (((n) & 0x000000000000ff00ull) << 40) \
      | (((n) & 0x00000000000000ffull) << 56) )
#  define htolell(n) bswap_64(n)
#  define letohll(n) bswap_64(n)
# endif /* GNUC & GLIBC */
#elif __THRIFT_BYTE_ORDER == __THRIFT_LITTLE_ENDIAN
#  define htolell(n) (n)
#  define letohll(n) (n)
# if defined(__GNUC__) && defined(__GLIBC__)
#  include <byteswap.h>
#  define ntohll(n) bswap_64(n)
#  define htonll(n) bswap_64(n)
# elif defined(_MSC_VER) /* Microsoft Visual C++ */
#  define ntohll(n) ( _byteswap_uint64((uint64_t)n) )
#  define htonll(n) ( _byteswap_uint64((uint64_t)n) )
# else /* Not GNUC/GLIBC or MSVC */
#  define ntohll(n) ( (((uint64_t)ntohl(n)) << 32) + ntohl(n >> 32) )
#  define htonll(n) ( (((uint64_t)htonl(n)) << 32) + htonl(n >> 32) )
# endif /* GNUC/GLIBC or MSVC or something else */
#else /* __THRIFT_BYTE_ORDER */
# error "Can't define htonll or ntohll!"
#endif

描述

该宏定义通过包含include <boost/detail/endian.hpp>来检测当前系统的字节序是哪种字节序,如果注释掉该引入头文件,默认当前系统是大端系统,从而定义

#  define htolell(n) (n)

#  define letohll(n) (n)

在网络传输数据时候,整型数据将不需要从小端系统格式转换成大端系统格式,直接进行网络发送

template <class Transport_>
uint32_t TBinaryProtocolT<Transport_>::writeDouble(const double dub) {
  BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
  BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);

  uint64_t bits = bitwise_cast<uint64_t>(dub);
  bits = htonll(bits);
  this->trans_->write((uint8_t*)&bits, 8);
  return 8;
}

问题

目前项目上发现传输给客户端的浮点型数据全部变成类似3.40788366E-312等异常数据,其他版本代码都是正常的,发现#  include <boost/detail/endian.hpp>被注释掉,导致htonll被宏定义为

#define htonll(n) (n)

没有转换为大端字节序

【文章出处:香港服务器 https://www.68idc.cn欢迎留下您的宝贵建议】
上一篇:【C生万物】 从0开始学习C语言
下一篇:没有了
网友评论