题
嘿,伙计们,问题从一个C/网络的新手...
我做了一些socket programming in C和试图搏斗字节的顺序问题。我请求(send)是好的但当我收到我的数据字节是所有的顺序。我开始像这样的东西...
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]);
}
这个工作的好时我要处理数据作为一个简短的,但是如果我把指针指向一个char再次字节是相反的。我做错了什么?
谢谢!
解决方案
好的,似乎有问题,你在做什么在两个不同的水平。部分混乱,在这里似乎干为使用的指针,什么类型的对象,他们点,然后将解释的编码的价值在存储器中指出,通过的指针(s)。
编码的多字节的实体记忆是什么样的被称为endianess.两个共同的编码是被称为 Little Endian (LE)和 Big Endian (BE)。LE,16位数量,像一个简短的编码最不重要的字节(LSB)第一次。在会,最显着的字节(MSB)编码的第一次。
通过《公约》网协议通常进行编码的事情为什么我们呼叫"网络byte order"(ADD),这也是一样。如果你发送和接收存缓冲区big endian平台,那么你不会跑到转换的问题。然而,你的代码,然后将依赖平台上的是公约》。如果你想要写的便携式码的正常工作的两勒和平台,你不应该假定平台endianess.
实现endian可携带性的目的程序喜欢 ntohs(), ntohl(), htons(), , htonl().这些功能/宏定义给定平台上进行必要的转换的发送和接收结束:
- htons() -转换短值主办了网络的顺序(用于发送)
- htonl() -转换的长期价值的自主机的以网络为(用于发送)
- ntohs() -转换短值从网为主的顺序(后收到)
- ntohl() -转换的长期价值从网为主的顺序(后收到)
明白你的意见,有关访问的存在铸回字没有影响在实际订单的实体在记忆。也就是说,如果你访问的缓冲区作为一系列的字,你会看到的字节的任何顺序,他们实际上编入存储,无论你是否有一个可或LE机。所以如果你正在看一个有编码的缓冲器后收到,MSB将是第一-始终如一。如果你看出缓冲器后,已转换回到主机订单,如果你有被机器,字节的顺序将保持不变。相反,在LE机字节将所有的现在可逆转的转换的缓冲区。
最后,在转换循环,变量 total
指字节。但是,要访问的缓冲作 shorts
.你的循环,保护不应该 total
, 但应该是:
total / sizeof( unsigned short )
考虑到双字节的性质,每 short
.
其他提示
此,当我处理该数据作为短,但是,如果我转换指针为char再次字节被颠倒工作正常。
这就是我所期待的。
我在做什么错了?
您必须知道发件人发送的内容:知道数据是否是字节(它不需要倒车)或短裤或多头(其中做的)
。谷歌用于与ntohs
,htons
关联的教程,和htons
的API。
目前还不清楚是什么aResponse
代表(字符字符串?结构?)。 字节序仅为数值,而不是char
s是相关的。你还需要确保在发送侧,所有数值被从主机转换为网络字节顺序(hton*
)。
除了你原来的问题(我认为已经回答了),你应该看看你的的malloc 的声明。 的malloc 分配字节和一个无符号短是最有可能是两个字节。
您的说法应该是这样的:
unsigned short *ptr = (unsigned short*) malloc(total * sizeof(unsigned short));
网络字节顺序是大端,所以你需要的,如果你想让它什么意义,将其转化为小端,但如果它仅仅是一个数组它不应该大惊小怪,请问在发送端发送它的数据?
有关单字节,我们可能不关心字节顺序。