MIPS 大端序和小端序的问题

 本文转载自链接:https://blog.csdn.net/Z_hehe/article/details/53310157

       果然,继上次移植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

 

编写程序判断大小端的两种方法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kit_9875507/article/details/44264663
posted @ 2019-11-30 14:29  大秦长剑  阅读(1710)  评论(0编辑  收藏  举报