| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 7165 人关注过本帖
标题:网络编程中,关于socket传输中的大小端问题
只看楼主 加入收藏
liuyeid
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2013-1-13
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:10 
网络编程中,关于socket传输中的大小端问题
在unix网络编成这本书中,提到过如果两台主机一个是大端一个是小端, 那么比如一端传输了一个short 的 0x0806那么对端就会收到 0x0608。(具体unix网络编成这本书是什么例子记得不大清楚了)

先来说说我的认识:
    在servaddr_in这个数据结构中,要给sin_port这个成员赋值就需要调用htons这个函数,来讲主机字节序装换位网络字节序,这就说明了一个问题,至少TCP或者UDP甚至SCTP协议或者说所有的四层协议(7层架构中),都不会去辨别主机是采用的什么字节序。这里我和同学有过一个讨论:
        首先在网络中传输是用的大端字节序,然后我们讨论结果是不会产生大小端问题,为什么呢?我们是基于这样的假设,当发送内存数据实,会自动判断主机                             字节序,然后转换为网络字节序发送出去,当接收方收到信息后判断自己的主机字节序,然后将网络字节序转为主机字节序,这样想好像是有道理的。因为网络字节序是标准的,只有一种字节序。

    但是先前我们说了要调用htons来转后端口号这个参数,所以协议是没有帮我们自动识别大小端问题的。所以肯定会出错的,而我们的讨论是基于协议会自动帮我们识别主机字节序然后座相应转换,的却,我也认为这样做是很有道理的,但是不知道现在的协议为什么没有这样做。

例子1大小端传输:
    如小端机器发送short的0x0806,即高地址存放0x08,低地址存放0x06----------发送的时候从低地址开始读取,即发送出去是0x0806--------大端主机依次读取从低地址开始存放数据,就是低地址存放0x06,高地址存放0x08,但是这个大端字节序,主机会把它解释为0x0608.

例子2大端到大端传输:
    如大端端机器发送short的0x0806,即高地址存放0x06,低地址存放0x08----------发送的时候从低地址开始读取,即发送出去是0x0608--------大端主机依次读取从低地址开始存放数据,就是低地址存放0x08,高地址存放0x06,主机会把它解释为0x0806.结果正确

例子3小端到小端传输:
    如小端机器发送short的0x0806,即高地址存放0x08,低地址存放0x06----------发送的时候从低地址开始读取,即发送出去是0x0806--------小端主机依次读取从低地址开始存放数据,就是低地址存放0x06,高地址存放0x08,主机会把它解释为0x0806.结果正确

    说明:我也不知道写数据到socket是否是从低地址写道高地址,我也使根据函数的参数猜测的,如write函数会已一个起始地址为参数然后加上一个长度参数,从参数来判断应该是从低地址到高地址写数据。

从这三个例子中可以看到一些信息。但是如果我的假设是对的(不管从高地址还是低地址开始向socket写数据还是接收的时候得行为,只要是一致的算对),那这里就有一个问题:在网络传输中好像没有体现出网络字节序的问题,还是说因为这个模式其实网络字节序对我们来说是透明的。

unix网络编程也说过发送字符数据就不会产生大小端问题,但是如果是java这样的语言怎么办,他的字符时两个字节的这不是也会产生大小端问题吗,还是java在向socket(网络)写数据的时候会调用类似htons的函数来转换每个字符数据,但是这样工作量是不是太大了。那java是怎么做的呢?

望大家来解答下我的疑问,或者帮我思考思考,我想这个问题很久了,也没有大端的机器来做做试验。。。。。。
搜索更多相关主题的帖子: 先来 
2013-01-13 13:13
liuyeid
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2013-1-13
收藏
得分:0 
大家有什么 想法可以q我,963547817,验证就写endian
2013-01-13 15:57
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:4 
你要长话短说,读完你的帖子,比吃安眠药还管用

unix网络编程说的字符,当然是指以字节为单位的字符,她管Java个屎呀
Java转不转我不知道,但为什么要转?或者说,将如Java不转,会出什么问题?
2013-01-14 08:45
Devil_W
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:9
帖 子:1160
专家分:1797
注 册:2009-9-14
收藏
得分:4 
不就是大尾数和小尾数的关系吗。

至于码那么多字?
2013-01-14 09:53
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:4 
以下是引用Devil_W在2013-1-14 10:53:47的发言:

不就是大尾数和小尾数的关系吗。

至于码那么多字?

Devil_W大牛几个月没出现了哈

The quieter you become, the more you can hear
2013-01-14 10:36
浅水无殇
Rank: 2
等 级:论坛游民
帖 子:123
专家分:75
注 册:2012-11-23
收藏
得分:4 

wula wual
2013-01-14 10:41
liuyeid
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2013-1-13
收藏
得分:0 
回复 3楼 rjsp
首先你要同意这个问题"c网络编程中,小端(大端)传输一个short类型的0x0806给一个大端(小端)机器,会解读成0x0608" ,不然接下来的讨论没有意义。抑或是我的这个认识是错误的。
当然c中的字符是一个字节,传字符肯定不会出错。但是java中的一个字符时两个字节,就会出现问题啊,就像short的0x0806会颠倒,如果java不转肯定是乱码的,但是估计java封装的那么多,肯定是自动转了的。
2013-01-14 12:07
liuyeid
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2013-1-13
收藏
得分:0 
回复 4楼 Devil_W
好吧,那简单一点,“在c c++ javac网络编程中,小端(大端)传输一个short类型的0x0806给一个大端(小端)机器,会不会解读成0x0608?" ,是这三种语言都回解读成0x0608,还是只是其中某几个或是都不会?帮帮忙,有点例子更好,就是没有大端处理器。。。在网上没有找到很好的回答或是资料
2013-01-14 12:11
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:4 
通讯讲究的是协议,先传约定,再传数据,这是规矩。

授人以渔,不授人以鱼。
2013-01-14 16:24
liuyeid
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2013-1-13
收藏
得分:0 
回复 9楼 TonyDeng
对阿,但是在四层 三层 二层都没有传输主机 是大端还是小端的字段。自由网络字节序是大端 的规定。还从htons这个函数来看四层协议也是 不识别 主机字节序。。。
2013-01-14 16:33
快速回复:网络编程中,关于socket传输中的大小端问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015745 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved