冒着被大家唾骂的风险大胆置疑: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工作站和网络字节序是一样的,也是大端的。