【发布时间】:2009-12-19 21:20:08
【问题描述】:
我正在尝试编写可以与任何可以建立套接字连接的标准客户端(例如 telnet 客户端)通信的服务器
它最初是一个回显服务器,当然不需要担心网络字节顺序。
我熟悉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]);
}
}
或类似的东西。上面的事情假设字大小是 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]);
}
运行这个 sn-p 代码。我的输出如下:
$ ./a.out
4 3 2 1
那些使用 powerPC 芯片组的人应该得到“1 2 3 4”,但我们这些使用 intel 芯片组的人应该看到我上面得到的大部分内容。
【问题讨论】:
-
我认为这取决于每个字符的大小。如果每个字符只使用一个字节,则无需担心。
-
如果您将 uint32_t* 转换为 char* 那么是的,顺序很重要。 “我们认为字节顺序对 char* 无关紧要”的意思是,如果你声明一个字符数组,并且只使用字符而不使用更大的类型,你不必交换,它只是多字节整数这很重要(uint32_t 是一个多字节整数,所以这就是您的示例的行为方式)。
-
您的示例代码不使用字符串,它使用
uint32_t的内存表示。有区别。如果您改为使用char *c = "foo";,则输出为 66、6f、6f、0。无论机器的字节序如何。我还没有编写回显客户端/服务器,但我已经用 C 编写了 HTTP 客户端和服务器。您不需要对字符串进行字节交换。 -
@Derrick:别再侮辱了。相反,你为什么不试试呢? char foo[] = "你好,世界";写(fd,foo,sizeof(foo)); -- 在 Intel 机器上执行 write() 并在 PowerPC 机器上执行 read() 并见证它是如何工作的。否则我建议你重新阅读这里的一些 cmets。
-
@Derrick:示例服务器:stackoverflow.com。它返回字符串,不同的客户端不需要做任何特殊的事情来检测服务器的字节顺序。
标签: c string network-programming portability endianness