什么是转换字节的便携方式

我试图编写服务器,将与任何可以进行套接字连接的标准客户端通信(例如,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 *,在收到数据后必须使用hnt *,正确的?

编辑:对于那些事情,因为1-char是一个字节,endian-ness无所谓:

int main(void)
{
    uint32_t a = 0x01020304;
    char* c = (char*)&a;
printf("%x %x %x %xn", c[0], c[1], c[2], c[3]);

}

运行这段代码。 我的输出如下:

$ ./a.out
  4 3 2 1

那些在powerPC芯片组上应该得到'1 2 3 4',但我们intel芯片组上的人应该看到我大部分上面得到的东西。


也许我在这里错过了一些东西,但是你会发送字符串,也就是字符序列吗? 那么你不需要担心字节顺序。 这只适用于整数中的位模式。 字符串中的字符总是处于“正确”的顺序。

编辑:

Derrick,为了解决你的代码示例,我在Intel i7(小端)和旧的Sun Sparc(大端)上运行了以下(稍微扩展)的程序版本,

#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 %xn", c[0], c[1], c[2], c[3]);
    printf("The string:  %x %x %x %xn", d[0], d[1], d[2], d[3]);
    return 0;
}

正如你所看到的,我已经添加了一个真正的字符数组到你的整数打印输出。

小端英特尔i7的输出:

The integer: 4 3 2 1
The string:  1 2 3 4

而大前锋Sun的输出:

The integer: 1 2 3 4
The string:  1 2 3 4

您的多字节整数的确在两台机器上以不同的字节顺序存储,但char数组中的字符具有相同的顺序。


通过发布的函数签名,您不必担心字节顺序。 它接受一个char *,它只能处理8位字符。 每个字符一个字节,不能有字节顺序问题。

如果您使用UTF16或UTF32编码发送Unicode,则只会遇到字节顺序问题。 并且发送机的序列号与接收机的序列号不匹配。 简单的解决方案是使用UTF8编码。 这是大多数文本在网络中发送的内容。 面向字节,它也没有字节顺序问题。 或者您可以发送物料清单。


如果您想将它们作为8位编码发送(您使用char的事实意味着这是您想要的),则不需要字节交换。 但是,对于非ASCII字符的无关问题,以便在连接的两端显示相同的字符> 127 ,我建议您以UTF-8的形式发送数据,这些数据可以表示所有的Unicode字符并可以安全地视为ASCII字符串。 根据默认编码获取UTF-8文本的方式因您使用的平台和库集而异。

如果您发送的是16位或32位编码......您可以包含一个带有字节顺序标记的字符,另一端可以用来确定字符的字节顺序。 或者,您可以假设网络字节顺序,并按照您的建议使用htons()htonl() 。 但是如果你想使用char ,请看前一段。 :-)

链接地址: http://www.djcxy.com/p/61895.html

上一篇: What's a portable way of converting Byte

下一篇: Detecting endianness programmatically in a C++ program