htonl 不使用与网络相关的标头

htonl without using network related headers

本文关键字:网络 htonl      更新时间:2023-10-16

我们正在编写嵌入式应用程序代码并验证字符串是否具有有效的IPv4格式。我能够成功地使用字符串分词器做到这一点,但现在我需要使用 htonl(( 函数将整数转换为主机到网络的顺序。

由于它是一个嵌入式应用程序,我不能仅仅为了使用 htonl(( 函数而包含网络标头和库。

C++有什么方法/非网络标头可以使用 htonl(( 功能吗?

来自htonl()的手册页:

htonl(( 函数将无符号整数 hostlong 从主机字节顺序转换为网络字节顺序。

网络字节顺序实际上只是大端序。

您需要做的就是编写(或查找(一个将无符号整数转换为大端序的函数,并使用它代替htonl。如果您的系统已经处于大端序,那么您根本不需要执行任何操作。


您可以使用以下命令来确定系统的字节序:

int n = 1;
// little endian if true
if(*(char *)&n == 1) {...}


您可以使用以下命令将小端序uint32_t转换为大端序:

uint32_t htonl(uint32_t x) {
unsigned char *s = (unsigned char *)&x;
return (uint32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
}

你并不严格需要htonl。如果您的 IP 地址为单个字节,如下所示:

uint8_t a [4] = { 192, 168, 2, 1 };

您可以通过网络以确切的顺序发送这 4 个字节。除非你特别需要它作为4字节整数,你可能不需要,因为你大概没有使用sockaddr_in和朋友。

如果您已经将地址作为主机字节顺序的 32 位整数,则可以获取如下a

uint32_t ip = getIPHostOrder();
uint8_t a [4] = { (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF };

这样做的优点是不依赖于实现定义的行为并且是可移植的。