嘿伙计们,来自C/Networking新手的问题......
我在C中进行一些套接字编程,并试图解决字节顺序问题.我的请求(发送)很好,但是当我收到数据时,我的字节都乱了.我从这样的事情开始......
char * aResponse= (char *)malloc(512); int total = recv(sock, aResponse, 511, 0);
在处理这个响应时,每个16位字似乎都反转了它(我正在使用UDP).我试图通过做这样的事来解决这个问题......
unsigned short * _netOrder= (unsigned short *)aResponse; unsigned short * newhostOrder= (unsigned short *)malloc(total); for (i = 0; i < total; ++i) { newhostOrder[i] = ntohs(_netOrder[i]); }
当我将数据视为short时,这可以正常工作,但是如果我再次将指针转换为char,则字节会反转.我究竟做错了什么?
谢谢!
好吧,你在两个不同的层面上做的事情似乎有问题.这里的部分混淆似乎源于你使用指针,它们指向什么类型的对象,然后解释指针所指向的内存中值的编码.
内存中多字节实体的编码被称为endianess.这两种常见编码称为Little Endian(LE)和Big Endian(BE).对于LE,像short这样的16位数量首先是编码最低有效字节(LSB).在BE下,首先编码最高有效字节(MSB).
按照惯例,网络协议通常将事物编码为我们称之为"网络字节顺序"(NBO)的东西,它也恰好与BE相同.如果您要在大端平台上发送和接收内存缓冲区,那么您将不会遇到转换问题.但是,您的代码将依赖于BE约定的平台.如果您想编写可在LE和BE平台上正常运行的可移植代码,则不应假设平台的endianess.
实现字节序可移植性是ntohs(),ntohl(),htons()和htonl()等例程的目的.这些函数/宏在给定平台上定义,以在发送和接收端进行必要的转换:
htons() - 将短值从主机顺序转换为网络顺序(用于发送)
htonl() - 将长值从主机顺序转换为网络顺序(用于发送)
ntohs() - 将短值从网络订单转换为主机订单(收到后)
ntohl() - 将长值从网络订单转换为主机订单(收到后)
了解在回送到字符时有关访问内存的注释不会影响内存中实体的实际顺序.也就是说,如果您将缓冲区作为一系列字节访问,您将看到它们实际编码到内存中的字节数,无论您有BE还是LE机器.因此,如果您在接收后查看NBO编码的缓冲区,MSB将始终是第一个.如果在转换回主机顺序后查看输出缓冲区,如果您有BE机器,则字节顺序将保持不变.相反,在LE机器上,现在所有字节都将在转换后的缓冲区中反转.
最后,在转换循环中,变量total
引用字节.但是,您正在访问缓冲区shorts
.你的循环警卫不应该total
,但应该是:
total / sizeof( unsigned short )
考虑每个的双字节性质short
.