MIPS 大端序和小端序的问题
果然,继上次移植Libjpeg到openWRT上的问题之后,新的问题又出现了,之前写的用RTP传输jpg图像到VLC的程序,在虚拟机上运行时没问题的,可是在交叉编译到开发板上的时候就不行了,图像数据是传输出去了,但是VLC端就是接收不到图像。最后用抓包工具抓包看了看才发现,抓的包是一团乱啊,在UDP头后面的RTP头数据完全乱套了。抓包还抓到了TCP的三次握手(搞不懂为啥),还有个什么加密什么来着(以为是加密,后来才发现想多了)。
没办法,从程序开始找问题啊,最后发现可能就是字节序的问题。果然,把倒着写的RTP头定义正着写,传输抓包时才能收到正确的RTP的头的设置,图像也能在VLC显示出来。
后来又去网上逛了逛,才发现,大部分的MIPS和网络字节序一样,为大端模式,而我平时在ubuntu的虚拟机和arm开发板上都是小端模式,这就要一个字节序转换函数(htonl,htons,),但是在MIPS上的大端模式就不用了,所以把程序里的字节序转换函数也去掉就行了。
顺便复习下大端序和小端序吧:
字节序,又称端序,尾序,英文:Endianness。
在计算机科学领域中,字节序是指存放多字节数据的字节(byte)的顺序,典型的情况是整数在内存中的存放方式和网络传输的传输顺序。Endianness有时候也可以用指位序(bit)。
大小端序跟硬件的体系结构有关,所有x86系列的pc机都是小端序,跟操作系统无关。在x86系列的pc上的solaris系统是小端序,sun sparc平台的solaris是大端序。
大端字节序,高字节存于内存低地址,低字节存于内存高地址;小端字节序反之。
如一个long型数据0x12345678
大端字节序:
内存低地址--> 0x12
0x34
0x56
内存高地址--> 0x78
小端字节序:
内存低地址--> 0x78
0x56
0x34
内存高地址--> 0x12
但是,当传输的数据以一个字节一个字节的方式进行发送传输的话,就没有大段序、小端序的问题了
判断CPU大小端的程序:
联合(union)方式判断法
在union中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同
的起始地址。即上述的union虽然定义了两个成员,但其实这个union只占用了4个字节(32位机器中),往a成员
赋值,然后读取b就相读取a成员的低位第一个字节的值。如果机器使用大端模式,则u.a=1那a的最高字节值为1;
如果机器使用小段模式,则u.a=1则a的最低位字节为1。上述可知b和a有相同的起始位,所以读取b如果等于1,
则为小端模式,b为0则为大端模式。
typedef union { int i; char c; }my_union; int checkSystem1(void) { my_union u; u.i = 1; return (u.i == u.c); }
————————————————
版权声明:本文为CSDN博主「Z_hehe」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/z_hehe/article/details/53310157