免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1531 | 回复: 8
打印 上一主题 下一主题

[网络子系统] tcp报文收发时, data offset 的ushort是否需要做字节序转换? [复制链接]

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-06-22 17:48 |只看该作者 |倒序浏览
  如下的黑体部分  

0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F |                               |
   | Offset | Res   |R|C|S|S|Y |I |            Window             |
   |           |          |G|K|H|T|N |N |                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+



struct tcphdr {
        __be16        source;
        __be16        dest;
        __be32        seq;
        __be32        ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
        __u16        res1:4,
                doff:4,
                fin:1,
                syn:1,
                rst:1,
                psh:1,
                ack:1,
                urg:1,
                ece:1,
                cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
        __u16        doff:4,
                res1:4,
                cwr:1,
                ece:1,
                urg:1,
                ack:1,
                psh:1,
                rst:1,
                syn:1,
                fin:1;
#else

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
2 [报告]
发表于 2016-06-22 18:19 |只看该作者
回复 1# mordorwww

就 4 个 bit,不需要转换的。直接用。字节序,是超过一个 byte 时需要考虑的。


   

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
3 [报告]
发表于 2016-06-23 08:48 |只看该作者
Godbach 发表于 2016-06-22 18:19
回复 1# mordorwww

就 4 个 bit,不需要转换的。直接用。字节序,是超过一个 byte 时需要考虑的。


我是问她所在的这个 ___u16不用转换吧

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
4 [报告]
发表于 2016-06-23 10:47 |只看该作者
回复 3# mordorwww

所在的 _u16 已经按照 bitfield 分出去了,你直接通过结构体对应的各自成员去访问就成了。你没有必要一下子读取整个 _u16 的值啊,或者是这个 _u16 的数值对你来说没有用处。

只有你需要一次读取超过 1 个 bytes 的数值时,才需要考虑字节序的转换。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
5 [报告]
发表于 2016-06-23 11:33 |只看该作者
本帖最后由 mordorwww 于 2016-06-23 11:45 编辑
Godbach 发表于 2016-06-23 10:47
回复 3# mordorwww

所在的 _u16 已经按照 bitfield 分出去了,你直接通过结构体对应的各自成员去访问就 ...


下面这种奇葩的定义见过没

我觉得应该是要对整个64bits做字节序转换,虽然位域没有超过或者达到8bits,但是好几个都跨bytes甚至跨short了。手头上没有big的CPU,没法验证

#if __BYTE_ORDER != __LITTLE_ENDIAN

        uint32_t Odo:32;
        uint16_t BmprHghtFnt:7;
        uint16_t BmprHghtRear:7;
        uint16_t VehHght:7;
        uint16_t VehMass:7;
        uint16_t VehType:4;

#else  // __BYTE_ORDER != __BIG_ENDIAN
        uint16_t VehType:4;
        uint16_t VehMass:7;
        uint16_t VehHght:7;
        uint16_t BmprHghtRear:7;
        uint16_t BmprHghtFnt:7;
        uint32_t Odo:32;

#endif

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
6 [报告]
发表于 2016-06-23 12:38 |只看该作者
回复 5# mordorwww

那你把数字反着写不能验证么?

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
7 [报告]
发表于 2016-06-23 12:39 |只看该作者
那你把数字反着写不能验证么?

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
8 [报告]
发表于 2016-06-23 16:45 |只看该作者
回复 5# mordorwww
这个人家结构体定义的时候已经考虑好了。你就按照单个成员访问就行了。超过一个字节的,要考虑这个问题。


   

论坛徽章:
13
程序设计版块每日发帖之星
日期:2016-06-29 06:20:00每日论坛发贴之星
日期:2016-08-14 06:20:00操作系统版块每日发帖之星
日期:2016-08-14 06:20:00每日论坛发贴之星
日期:2016-08-13 06:20:00数据库技术版块每日发帖之星
日期:2016-08-13 06:20:00程序设计版块每日发帖之星
日期:2016-08-13 06:20:00IT运维版块每日发帖之星
日期:2016-08-13 06:20:00每日论坛发贴之星
日期:2016-08-12 06:20:00数据库技术版块每日发帖之星
日期:2016-08-12 06:20:00程序设计版块每日发帖之星
日期:2016-08-12 06:20:00操作系统版块每日发帖之星
日期:2016-08-12 06:20:00综合交流区版块每日发帖之星
日期:2016-08-09 06:20:00
9 [报告]
发表于 2016-06-26 09:22 |只看该作者
本帖最后由 karma303 于 2016-06-26 09:27 编辑

  结构体内bitfield的顺序是对byte endian敏感的。
  并不是说x86或MIPS除了byte order之外,还有bit order的区别。
  这个问题的根源在于编译器。纯粹是编译器作怪。展开讲话就多了。暂且不表。
  不过我可以告诉你一个技巧,如果位域不跨字节的,大小端的变换是有规律的。
  像小端模式的一个结构体:
struct abcdef {
        int a: 4;
        int b: 4;
        int c: 4;
        int d: 2;
        int e: 2;
};
你想让它在MIPS上的gcc编译后有同样的内存布局,方法是:从上到下,位域每8个bit一组,反转组内的成员顺序。结果是这样:
struct abcdef {
        int b: 4;
        int a: 4;
        int e: 2;
        int d: 2;
        int c: 4;
};
如果位域跨字节,那我就没有办法了。你贴出来的那个struct video什么的代码,我是看不懂的。

一般这种针对big/little endian的条件编译,是出于两种场合的需要。
(1)网络底层协议的传输,从host A传到 host B上,相当于一份远程的内存拷贝,网络协议必须规定这段内存(记作xxx)该以big or little endian的方式存放数据。 我们上面代码里#if #else条件编译,其实都是折腾编译器。我们希望我们的代码在MIPS和x86机器编译后,希望类似下面的代码的输出是一致的:
----------------------------------------------
  struct tcphdr *hdr = (void *)xxx  ;
  printf( "%d\n", hdr->res1);
---------------------------------------------

(2) 驱动代码里,我们要把bitfield与寄存器对应死。

自己写的一篇帖子,希望对题主有帮助。http://bbs.chinaunix.net/forum.p ... =4248004&extra=
  
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP