标签: htonl

在C++中是否有64位整数的"标准"类似htonl的函数?

我正在研究memcache协议的实现,在某些点上,它使用64位整数值.这些值必须以"网络字节顺序"存储.

我希望有一些uint64_t htonll(uint64_t value)功能可以进行更改,但不幸的是,如果它存在,我找不到它.

所以我有1或2个问题:

  • 是否有任何可移植(Windows,Linux,AIX)标准功能?
  • 如果没有这样的功能,你会如何实现它?

我想到了一个基本的实现,但我不知道如何在编译时检查字节序以使代码可移植.所以你的帮助非常受欢迎;)

谢谢.


这是我写的最终解决方案,感谢Brian的解决方案.

uint64_t htonll(uint64_t value)
{
    // The answer is 42
    static const int num = 42;

    // Check the endianness
    if (*reinterpret_cast<const char*>(&num) == num)
    {
        const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
        const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));

        return (static_cast<uint64_t>(low_part) << 32) | high_part;
    } else
    {
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)

c++ 64-bit portability endianness htonl

60
推荐指数
4
解决办法
4万
查看次数

ntohs()和ntohl()等价?

在C#中是否有网络主机转换功能?谷歌搜索并没有找到太多.:P

c# htonl

32
推荐指数
2
解决办法
2万
查看次数

有符号和无符号int之间的强制转换是否在内存中保持变量的精确位模式?

我想x通过套接字传递一个32位有符号整数.为了让接收器知道预期的字节顺序,我htonl(x)在发送之前调用.htonl期待一个,uint32_t但我想确定当我把我int32_t带到一个时会发生什么uint32_t.

int32_t x = something;
uint32_t u = (uint32_t) x;
Run Code Online (Sandbox Code Playgroud)

总是这样的情况,每个字节xu每个字节都完全相同吗?怎么回事:

uint32_t u = something;
int32_t x = (int32_t) u;
Run Code Online (Sandbox Code Playgroud)

我意识到负值会转换为大的无符号值,但这并不重要,因为我只是回到了另一端.但是,如果使用实际字节进行混乱,那么我无法确定返回将返回相同的值.

c int unsigned casting htonl

27
推荐指数
2
解决办法
2万
查看次数

如何将sockaddr_in6 :: sin6_addr字节顺序设置为网络字节顺序?

我开发网络应用程序并使用套接字API.

我想设置sockaddr_in6结构的sin6_addr字节顺序.

对于16位或32位变量,很简单:使用htons或htonl:

// IPv4
sockaddr_in addr;
addr.sin_port = htons(123);
addr.sin_addr.s_addr = htonl(123456);
Run Code Online (Sandbox Code Playgroud)

但对于128位变量,我不知道如何将字节顺序设置为网络字节顺序:

// IPv6
sockaddr_in6 addr;
addr.sin6_port = htons(123);
addr.sin6_addr.s6_addr = ??? // 16 bytes with network byte order but how to set?
Run Code Online (Sandbox Code Playgroud)

一些答案可能是使用htons 8次(2*8 = 16字节),或使用htonl 4次(4*4 = 16字节),但我不知道哪种方法是正确的.

谢谢.

sockets networking byte htonl

10
推荐指数
1
解决办法
1万
查看次数

便携式C二进制序列化原语

据我所知,C库没有帮助将数值序列化为非文本字节流.如我错了请纠正我.

最常用的标准工具是htonlPOSIX等.这些功能有缺点:

  • 没有64位支持.
  • 没有浮点支持.
  • 签名类型没有版本.反序列化时,无符号到符号的转换依赖于有符号整数溢出,即UB.
  • 它们的名称没有说明数据类型的大小.
  • 它们依赖于8位字节和精确大小的uint_ N _t的存在.
  • 输入类型与输出类型相同,而不是引用字节流.
    • 这要求用户执行指针类型转换,这可能在对齐时不安全.
    • 执行该类型转换后,用户可能会尝试在其本机内存布局中转换和输出结构,这种做法很糟糕,导致意外错误.

用于将任意大小序列化为char8位标准字节的接口将落在C标准之间,该标准不真正确认8位字节,并且无论标准(ITU?)将八位位组设置为基本传输单位.但旧的标准没有得到修订.

现在C11有许多可选组件,可以添加二进制序列化扩展以及线程之类的东西,而不需要对现有实现提出要求.

这样的扩展是否有用,或者担心非二进制补充机器是否毫无意义?

c portability binaryfiles endianness htonl

10
推荐指数
1
解决办法
2183
查看次数

混乱的htons-小端/大端

当我通过套接字将一个整数变量从一个进程发送到另一个进程,然后在接收端打印该值时,如果不使用ntohl/htonl,该值仍然相同,那么除了初始化套接字结构之外,我还需要使用这些函数.我理解litte/big endian.但是,当值保持不变时,为什么我们需要将端口和IP nos转换为主机/网络字节顺序.请详细解释整数是如何通过网络传输的?

c network-programming endianness htonl

9
推荐指数
2
解决办法
1万
查看次数

主机到网络双?

我想通过网络发送一些双精度浮点数.(标准C,标准套接字)没有htond或ntohd将数据转换为网络字节顺序和从网络字节顺序转换数据.我该怎么办?我脑子里有几个解决方案,但我想知道常见的做法是什么.

(我也想知道发送64位整数的常见做法,比如gstreamer使用的gint64值)

编辑:这是我想到的一个解决方案.我认为它适用于任何大小的整数,但它是否适合双打?

void swap_if_necessary (void* buff, int buff_len) 
{
    uint32_t foo = 1;
    if ( htonl(foo) != foo ) 
    {
        char* to_swap = (char*)buff;

        int i;
        for (i = 0; i < buff_len/2; i++)
        {
            char  swap_buff = to_swap[i];
            to_swap[i] = to_swap[buff_len -1 -i];  
            to_swap[buff_len -1 -i] = swap_buff;
        }  
    }
}
Run Code Online (Sandbox Code Playgroud)

c sockets double double-precision htonl

5
推荐指数
2
解决办法
5515
查看次数

何时以及如何使用C ++ htonl函数

cout << "Hello World !" << endl;
Run Code Online (Sandbox Code Playgroud)

对于我关于堆栈溢出的第一篇文章:我们什么时候应该使用该htonl函数?我已经浏览了手册页。但是,我不太了解何时以及如何使用它。

c++ htonl

5
推荐指数
1
解决办法
7966
查看次数

_byteswap_uint64 和 _byteswap_ulong 的跨平台定义

Visual Studio的定义_byteswap_uint64_byteswap_ulongstdlib.h

我是否正确地假设,这不是标准的并且不会在 Linux 或 Darwin 上编译?

有没有办法以跨平台的方式定义这些包含?

cross-platform include endianness htonl

5
推荐指数
1
解决办法
6119
查看次数

如何在Linux内核中将__u32转换为__be32

我有一个变量

__be32 x;
Run Code Online (Sandbox Code Playgroud)

我有一个功能

__u32 foo(void){
      __u32 a;
      return a;
}
Run Code Online (Sandbox Code Playgroud)

我需要在变量中存储foo的返回值x.

x=htonl(foo());
Run Code Online (Sandbox Code Playgroud)

这是对的吗?我有一个困惑是什么的返回类型ntohl()htonl().它们彼此相反吗?

要检查输出,我需要重新编译内核,我不想让我的系统出现任何错误.所以我在这里问.

c linux-kernel htonl

3
推荐指数
1
解决办法
3391
查看次数