Der*_*ick 2 c string portability network-programming endianness
我正在尝试编写服务器,它将与任何可以建立套接字连接的标准客户端进行通信(例如telnet客户端)
它最初是一个echo服务器,当然不需要担心网络字节排序.
我熟悉ntohs,ntohl,htons,htonl函数.如果我传输的是16位或32位的整数,或者发送的字符串中的字符是2或4字节的倍数,那么它们本身就很棒.
我想创建一个对字符串进行操作的函数,例如:
str_ntoh(char* net_str, char* host_str, int len)
{
uint32_t* netp, hostp;
netp = (uint32_t*)&net_str;
for(i=0; i < len/4; i++){
hostp[i] = ntoh(netp[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
或类似的东西.上面的假设是单词大小为32位.我们不能确定发送机器上的字数不是16位还是64位正确?
对于客户端程序,例如telnet,它们必须在发送之前使用hton*,在接收数据后使用ntoh*,对吗?
编辑:对于那些人,因为1-char是一个字节,字节序无关紧要:
int main(void)
{
uint32_t a = 0x01020304;
char* c = (char*)&a;
printf("%x %x %x %x\n", c[0], c[1], c[2], c[3]);
}
Run Code Online (Sandbox Code Playgroud)
运行此代码段.我的输出如下:
$ ./a.out
4 3 2 1
Run Code Online (Sandbox Code Playgroud)
那些关于powerPC芯片组的人应该得到'1 2 3 4'但我们这些关于intel芯片组的人应该看看我上面得到的东西.
Tho*_*thy 17
也许我在这里遗漏了一些东西,但是你在发送字符串,即字符序列?那你就不用担心字节顺序了.这仅适用于整数中的位模式.字符串中的字符始终采用"正确"的顺序.
编辑:
Derrick,为了解决您的代码示例,我在Intel i7(little-endian)和旧的Sun Sparc(big-endian)上运行了以下(略微扩展)的程序版本
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint32_t a = 0x01020304;
char* c = (char*)&a;
char d[] = { 1, 2, 3, 4 };
printf("The integer: %x %x %x %x\n", c[0], c[1], c[2], c[3]);
printf("The string: %x %x %x %x\n", d[0], d[1], d[2], d[3]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我已经为您打印的整数添加了一个真正的char数组.
小端英特尔i7的输出:
Run Code Online (Sandbox Code Playgroud)The integer: 4 3 2 1 The string: 1 2 3 4
并且来自big-endian Sun的输出:
Run Code Online (Sandbox Code Playgroud)The integer: 1 2 3 4 The string: 1 2 3 4
您的多字节整数确实以不同的字节顺序存储在两台机器上,但char数组中的字符具有相同的顺序.