Thrift传输中,如何解析大小端系统字节序转换的复杂过程?

2026-04-12 01:551阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计697个文字,预计阅读时间需要3分钟。

Thrift传输中,如何解析大小端系统字节序转换的复杂过程?

说明:libthrift/src/thrift/protocol/TProtocol.h 文件中定义了 __THRIFT_BYTE_ORDER,它决定了当前系统使用的是大端字节序还是小端字节序来存储数据。这个定义对于数据的存储和传输非常重要。以下是相关代码片段:

c// thrift/protocol/TProtocol.h

// 定义大端字节序#define __THRIFT_BIG_ENDIAN 0

Thrift传输中,如何解析大小端系统字节序转换的复杂过程?

// 定义小端字节序#define __THRIFT_LITTLE_ENDIAN 1

// 根据系统平台设置字节序#if defined(__APPLE__) || defined(__linux__)#define __THRIFT_BYTE_ORDER __THRIFT_LITTLE_ENDIAN#elif defined(_WIN32)#define __THRIFT_BYTE_ORDER __THRIFT_LITTLE_ENDIAN#else#define __THRIFT_BYTE_ORDER __THRIFT_BIG_ENDIAN#endif

说明

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)

没有转换为大端字节序

本文共计697个文字,预计阅读时间需要3分钟。

Thrift传输中,如何解析大小端系统字节序转换的复杂过程?

说明:libthrift/src/thrift/protocol/TProtocol.h 文件中定义了 __THRIFT_BYTE_ORDER,它决定了当前系统使用的是大端字节序还是小端字节序来存储数据。这个定义对于数据的存储和传输非常重要。以下是相关代码片段:

c// thrift/protocol/TProtocol.h

// 定义大端字节序#define __THRIFT_BIG_ENDIAN 0

Thrift传输中,如何解析大小端系统字节序转换的复杂过程?

// 定义小端字节序#define __THRIFT_LITTLE_ENDIAN 1

// 根据系统平台设置字节序#if defined(__APPLE__) || defined(__linux__)#define __THRIFT_BYTE_ORDER __THRIFT_LITTLE_ENDIAN#elif defined(_WIN32)#define __THRIFT_BYTE_ORDER __THRIFT_LITTLE_ENDIAN#else#define __THRIFT_BYTE_ORDER __THRIFT_BIG_ENDIAN#endif

说明

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)

没有转换为大端字节序