冒着被大家唾骂的风险大胆置疑:UNP书中的一道关于主机序与网络序习题的答案?请进入热烈讨论?

冒着被大家唾骂的风险大胆置疑:UNP书中的一道关于主机序与网络序习题的答案?请进入热烈讨论?  [已结帖,结帖人:yaoike]
 
 加为好友
发送私信
在线聊天
yaoike
想念着Run的Ike
等级:
可用分等级:乞丐
总技术分:1
总技术分排名:331475
结帖率:97.37%

 发表于:2009-06-10 11:55:28 楼主


如题:小弟看的是UNP的第二版,pdf格式的电子书,刚看完UNP的第4章,在看该章4.1习题与该书中给出的
  答案后,不解,后写了个小程序在big-endian 和 little-endian 中运行,根据运行的结果,我觉得UNP
  第二版中的习题答案是错误的。
 
  请看UNP第二版4.1的习题:(pdf书的第109页)
  4.1 在4.4节中,我们说头文件 <netinet/in.h>中定义的常值INADDR_是主机字节序的,如何辨别?
 
  而后,本书中给出的答案是(pdf书的第812页)
  4.1 例如D类多播地址INADDR_MAX_LOCAL_GROUP定义成0xe00000ff,其注释为"224.0.0.255",它
  显然是按主机字节序定义的。
 
  我的看法却是就因为其注释为"224.0.0.255",所以应该是按网络字节序的。
 
  为此,我写了下面的一个小程序,也印证了我的看法。程序如下:

#include <stdio.h>
#include <stdlib.h>


void
main(int argc, char **argv)
{

union {
long int  l;
char  c[sizeof(long int)];
    } myun;

myun.l = 0x52535400;
if (sizeof(long int) == 4) {
if (myun.c[0] == 0x52 && myun.c[1] == 0x53)
printf("big-endian/n");
else if (myun.c[0] == 0x00 && myun.c[1] == 0x54)
printf("little-endian/n");
else
printf("unknown/n");
}
char *pChar = (char *)&myun.l;
int i;
for (i = 0; i < 4; i++)
{
printf("pChar(0x%0x) = 0x%0x/n", pChar, *pChar);
pChar++;
}


printf("myun.c = %s/n", myun.c);
printf("myun.c add = 0x%0x/n", myun.c);
printf ("myun.c = 0x%0x.0x%0x.0x%0x.0x%0x/n",
myun.c[0], myun.c[1], myun.c[2], myun.c[3]);

exit(0);

}

 
 
  该程序在主机字节序的环境下运行的结果是:
 
little-endian
pChar(0x12ff7c) = 0x0
pChar(0x12ff7d) = 0x54
pChar(0x12ff7e) = 0x53
pChar(0x12ff7f) = 0x52
myun.c =
myun.c add = 0x12ff7c
myun.c = 0x0.0x54.0x53.0x52
 
  在网络字节序的环境下的运行结果是:

big-endian
pChar(0xffbffd24) = 0x52
pChar(0xffbffd25) = 0x53
pChar(0xffbffd26) = 0x54
pChar(0xffbffd27) = 0x0
myun.c = RST
myun.c add = 0xffbffd24
myun.c = 0x52.0x53.0x54.0x0

 
这不恰恰说明4.1习题的答案应该是网络字节序的吗?请大家指教?谢谢!
 
 
问题点数:60 回复次数:17 显示所有回复显示星级回复显示楼主回复 修改 删除 举报 引用 回复  
 

 加为好友
发送私信
在线聊天
 appleshao
 
等级:
可用分等级:中农
总技术分:442
总技术分排名:38965

 发表于:2009-06-10 12:49:231楼 得分:2
消灭0回复
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 nlylidb
该用户很懒,没有设置昵称
等级:
可用分等级:贫农
总技术分:445
总技术分排名:46642

 发表于:2009-06-10 13:06:382楼 得分:15
看不懂你想说明什么。你的程序貌似只是说明了int类型在不同机器中的存储方式不同,也就是所谓的大端或小端,你的例子中没有一点和网络字序扯上关系。
你要想验证的话应该是比较int_addr(“224.0.0.255”)的结果与宏定义中的0xe00000ff相比,看结果是否相同。
在大端环境下两者是相同的,格式与主机序和网络序都相同,在小端环境下,两者是不同的,而宏定义为主机序。

给个程序你看看

C/C++ code
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>

int main()
{
        //宏定义中的格式
    int locale_addr = 0xe00000ff;
        //代表的ip地址
    char *ip = "224.0.0.255";
        //将ip地址转换为网络字节序的格式
    int net_addr = inet_addr(ip);
        //判断主机序与网络序是否相同
    if (locale_addr == net_addr)
    {
        printf("相同/n");
    }
    else
    {
        printf("不同/n");
    }
    return 0;
}

 

这个程序的输出结果在小端环境下是不同,说明宏定义的常值是主机序的
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 yaoike
想念着Run的Ike
等级:
可用分等级:乞丐
总技术分:1
总技术分排名:331475

 发表于:2009-06-10 13:56:293楼 得分:0
哦,非常感谢!
    我理解了你的看法。但是不明白你为什么说:
你的程序貌似只是说明了int类型在不同机器中的存储方式不同,也就是所谓的大端或小端,你的例子中没有一点和网络字序扯上关系。
你可否再详细说明一下,
我的理解是大端就是网络字节序,小端就是主机字节序,不知道理解得对不对。
还有一点,可否详细说明一下,为什么从你的思路可以解释得通它是主机字节序,而从我的思路上却解释不通呢?多谢!
 
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 goodname
叶落知秋
等级:
可用分等级:掌柜
总技术分:24429
总技术分排名:557
3
2
 发表于:2009-06-10 13:59:564楼 得分:5
我的理解是大端就是网络字节序,小端就是主机字节序,不知道理解得对不对。

后半句不正确。
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 lin_style
JAVA卧底、二分流掌门人
等级:
可用分等级:中农
总技术分:3515
总技术分排名:6427

 发表于:2009-06-10 14:04:525楼 得分:10
无论是大端还是小端,是一个标准。
比如网络中传输采用的是大端,而实际中的PC是根据CPU架构来决定是小端还是大端
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 yaoike
想念着Run的Ike
等级:
可用分等级:乞丐
总技术分:1
总技术分排名:331475

 发表于:2009-06-10 14:06:576楼 得分:0
还有,为什么你说:
这个程序的输出结果在小端环境下是不同,说明宏定义的常值是主机序的 ,

这不恰恰说明宏定义的常值是网络序吗?
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 lin_style
JAVA卧底、二分流掌门人
等级:
可用分等级:中农
总技术分:3515
总技术分排名:6427

 发表于:2009-06-10 14:07:527楼 得分:5
你是把little-endian 和网络字节序看成是不同本质的概念了。
把数字化的表示和224.0.0.255字符串的表示看混了。
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 yaoike
想念着Run的Ike
等级:
可用分等级:乞丐
总技术分:1
总技术分排名:331475

 发表于:2009-06-10 14:07:538楼 得分:0
to: 落叶知秋
  为什么说:
我的理解是大端就是网络字节序,小端就是主机字节序,不知道理解得对不对。

后半句不正确。

可否说明一二。
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 yaoike
想念着Run的Ike
等级:
可用分等级:乞丐
总技术分:1
总技术分排名:331475

 发表于:2009-06-10 14:57:349楼 得分:0
还有,为什么你说:
这个程序的输出结果在小端环境下是不同,说明宏定义的常值是主机序的 ,

这不恰恰说明宏定义的常值是网络序吗?

我又查了一下,
是不是说:主机字节序有可以是大端,也有可能是小端,
主机字节序是与CPU有关的,如Intel就是低位在前,高位在后 ,是小端。

为什么你说:这个程序的输出结果在小端环境下是不同,说明宏定义的常值是主机序的 ,主机序可以根据一个宏定义的常值来判定吗?


 
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 hairetz
风过留痕,雨过留印
等级:
可用分等级:掌柜
总技术分:59127
总技术分排名:144
4
5
 发表于:2009-06-10 15:12:5310楼 得分:5
引用 3 楼 yaoike 的回复:
哦,非常感谢!
    我理解了你的看法。但是不明白你为什么说:
你的程序貌似只是说明了int类型在不同机器中的存储方式不同,也就是所谓的大端或小端,你的例子中没有一点和网络字序扯上关系。
你可否再详细说明一下,
我的理解是大端就是网络字节序,小端就是主机字节序,不知道理解得对不对。
还有一点,可否详细说明一下,为什么从你的思路可以解释得通它是主机字节序,而从我的思路上却解释不通呢?多谢!

 

你就想问大端就是网络字节序?确实没错啊。

其实网络字节序就是指定大端字节序。
http://www.cnblogs.com/kevinmeng/archive/2009/04/19/1439068.html
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 nlylidb
该用户很懒,没有设置昵称
等级:
可用分等级:贫农
总技术分:445
总技术分排名:46642

 发表于:2009-06-10 15:23:2011楼 得分:5
刚睡觉起来。在小端中头文件定义的是0xe00000ff 表示的地址224.0.0.255,而从ip地址字符串通过函数inet_addr得到的二进制地址与前面的是不相同的,显然转化得到的是大端的网络序,而头文件中就是小端的主机序。

说它是主机序是说定义的宏是以主机序来存储的。
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 yaoike
想念着Run的Ike
等级:
可用分等级:乞丐
总技术分:1
总技术分排名:331475

 发表于:2009-06-10 16:03:4112楼 得分:0
我反复看了你的话不下30遍。还有有点不清楚,还望你指点:

  在小端中头文件定义的是0xe00000ff 表示的地址224.0.0.255,而从ip地址字符串通过函数inet_addr得到的二进制地址与前面的是不相同的,显然转化得到的是大端的网络序,而头文件中就是小端的主机序。

说它是主机序是说定义的宏是以主机序来存储的。


是不是可以理解为:

  在小端中头文件定义的是0xe00000ff 表示的地址224.0.0.255,而从ip地址字符串通过函数inet_addr得到的二进制地址与前面的是不相同的,显然转化得到的是大端的网络序(net_addr),(而因为locale_addr 与net_addr不同,所以,)而头文件中就是小端的主机序。

说它是主机序是说: 宏是以主机序存储的方式来定义的。
   
  但我还是不明白最后一句:说它是主机序是说定义的宏是以主机序来存储的。
    既然存储在主机上,任何宏不是以主机序来存储的吗?难道存储在主机上的宏可以以网络序的方式来存储吗?谢谢!
 
 
 
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 yaoike
想念着Run的Ike
等级:
可用分等级:乞丐
总技术分:1
总技术分排名:331475

 发表于:2009-06-10 16:34:1213楼 得分:0
我又想了一下,似乎想明白了,我讲一下我的看法,不知道对不对,请指正:

你写的程序(我做了一点修改)

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>

int main()
{
        //宏定义中的格式
    //int locale_addr = 0xe00000ff;
        //代表的ip地址
    char *ip = "224.0.0.255";
        //将ip地址转换为网络字节序的格式
    int net_addr = inet_addr(ip);
        //判断主机序与网络序是否相同
    if (INADDR_MAX_LOCAL_GROUP == net_addr)
    {
        printf("相同/n");
    }
    else
    {
        printf("不同/n");
    }
    return 0;
}


这个程序的输出结果:  在主机字节序是小端环境下的输出结果为:"不同",
                      在主机字节序是大端环境下的输出结果为:"相同"。

因此,可以知道,
宏:
#define INADDR_MAX_LOCAL_GROUP  ((in_addr_t) 0xe00000ff) /* 224.0.0.255 */

的定义为 0xe00000ff ,这样子定义的话,就造成了 该宏与主机字节序密切相关。输出结果(不同/相同)与主机字节序的环境(小端/大端)密切相关。

而如果是 该宏与网络字节序定义的话,那该程序的 测试结果 就与主机字节序(小端/大端)无关了。输出结果始终是"相同"。
   
 
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 mymtom
mymtom
等级:
可用分等级:富农
总技术分:13218
总技术分排名:1451
2
 发表于:2009-06-10 20:04:5914楼 得分:1
楼主看书还真是仔细。
值得学习哦,
顶一下。
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 yaoike
想念着Run的Ike
等级:
可用分等级:乞丐
总技术分:1
总技术分排名:331475

 发表于:2009-06-11 13:59:5615楼 得分:0
顶一下,请问大家我13楼所说的对不对呀?

 
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 hairetz
风过留痕,雨过留印
等级:
可用分等级:掌柜
总技术分:59127
总技术分排名:144
4
5
 发表于:2009-06-11 14:36:1416楼 得分:5
引用 15 楼 yaoike 的回复:
顶一下,请问大家我13楼所说的对不对呀?

 

不清楚宏本身到底是不是网络字节序,因为你想测试的话,把宏赋值给一个变量,这个时候,变量的存储已经是本机的字节序了。
 
修改 删除 举报 引用 回复  
 
 加为好友
发送私信
在线聊天
 pathuang68
玄机逸士
等级:
可用分等级:贫农
总技术分:6373
总技术分排名:3805

 发表于:2009-06-11 14:46:5817楼 得分:7
引用 8 楼 yaoike 的回复:
to: 落叶知秋
  为什么说:
我的理解是大端就是网络字节序,小端就是主机字节序,不知道理解得对不对。

后半句不正确。

可否说明一二。


补充说明一下:
“小端就是主机字节序”这句话不正确。
严格来说,是这句话不完全正确。对于某些机器,如我们通常用的PC,“小端就是主机字节序”是对的,但对于另外一些机器如Sun的工作站(包括服务器),这句话就是错的,因为Sun工作站和网络字节序是一样的,也是大端的。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值