社区
Linux/Unix社区
帖子详情
结构体和网络字节序问题
大耳
2006-04-29 08:46:37
typedef struct STag{
char a0;
char aa[4];
unsigned short a1;
unsigned short b;
unsigned short c;
int d;
float e;
double f;
char *g;
int *h;
}S;
linux下,
上面这个结构要通过网络传输出去,问如何处理结构填充空洞和网络字节序。
如果哪位 高手能写出大致的伪代码 ?
3x
...全文
644
15
打赏
收藏
结构体和网络字节序问题
typedef struct STag{ char a0; char aa[4]; unsigned short a1; unsigned short b; unsigned short c; int d; float e; double f; char *g; int *h; }S; linux下, 上面这个结构要通过网络传输出去,问如何处理结构填充空洞和网络字节序。 如果哪位 高手能写出大致的伪代码 ? 3x
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
15 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
fierygnu
2006-04-29
打赏
举报
回复
* 如果没有对齐,在发送的时候会不会把空洞里面的数据发出去呢?
===
会。send不区分结构,只是当作字节流。
* 浮点型呢怎么办?
===
也需要转换。到网上搜一下,有转换函数库。
fierygnu
2006-04-29
打赏
举报
回复
没找到为什么结贴了?:)
http://schwehr.org/software/density/
大耳
2006-04-29
打赏
举报
回复
现在问题是
* 如果没有对齐,在发送的时候会不会把空洞里面的数据发出去呢?
* 浮点型呢怎么办?
S.f = htonl((unsigned long)f); //这样就可以了?但是把double f变成unsigned long会不会使数据出错
高手帮忙看看,我也马上试验下看
大耳
2006-04-29
打赏
举报
回复
或者
toSend[0] = S.a0; // char a0;
toSend[1] = aa[0]; //char aa[4];
...
toSend[6] = htons(a1); // ; 这里强制转换,会自动把a1的低位放到toSend[7]??
或者再定义一个
S.a1 = htons(a1); 然后发送S=====这样似乎比较好,
但是
浮点型呢怎么办?
S.f = htonl((unsigned long)f); //这样就可以了?但是把double f变成unsigned long会不会使数据出错?
大耳
2006-04-29
打赏
举报
回复
如果没有对齐,在发送的时候会不会把空洞里面的数据发出去呢?
考虑移植性,应该使用htonl等函数,就是说,要另外建立一个数组,然后把结构一个一个的处理后,填入?
S myS;
unsigned char toSend[sizeof(S)]; // 这个sizeof得到的会比我要发的数据大呀?
然后
toSend[0] = S.a0; // char a0;
toSend[1] = aa[0]; //char aa[4];
...
toSend[6] = a1 // unsigned short a1; 这里强制转换,会自动把a1的低位放到toSend[7]??
// 或者用 toSend[6] = a1 & 0xff;
// toSend[7] = (a1>>8) & oxff;
.
.
.
字与码
2006-04-29
打赏
举报
回复
如果你的所有机器的系统都是一样的,也就是肯定没有字节序不一致的情况,可以不考虑字节序的问题(比如如果都是x86体系,就不用考虑)。否则就需要对每个结构成员调用htonl或者ntohl函数在网络字节和本地字节之间转换。
字与码
2006-04-29
打赏
举报
回复
你可以把char和short都换成int,就可以对齐了。或者char后面加上一个char reserved[3]凑齐4字节。
大耳
2006-04-29
打赏
举报
回复
ps 系统存储器是4字节对齐的
大耳
2006-04-29
打赏
举报
回复
还是不行哎~~~
调用htonf 时必须把参数强制转换为unsigned long,
这样做和调用htonl没什么区别了,
所以可是 (unsigned long )0.5 ===> 0
好郁闷呀
fierygnu
2006-04-29
打赏
举报
回复
浮点数的格式虽然有IEEE标准,但不是大家都用。
大耳
2006-04-29
打赏
举报
回复
呵呵,找到了,多谢多谢
#define htonf(x) (endian()?(x):swapf(x))
static int
endian()
{
static int init = 0;
static int endian_value;
char *p;
if (init) return endian_value;
init = 1;
p = (char*)&init;
return endian_value = p[0]?0:1;
}
#ifndef swap32
#define swap32(x) ((((x)&0xFF)<<24) \
|(((x)>>24)&0xFF) \
|(((x)&0x0000FF00)<<8) \
|(((x)&0x00FF0000)>>8) )
#endif
其实是自己做字节调换,
只是奇怪 这么重要的函数为什么不是 系统函数,
fierygnu
2006-04-29
打赏
举报
回复
呵呵,怎么搜的?google htonf
大耳
2006-04-29
打赏
举报
回复
不过可以肯定的是不能调用htonl来处理浮点型。我试过了,类型转换时,都变成了0 :(
大耳
2006-04-29
打赏
举报
回复
关键是浮点型麻烦, fierygnu(va_list) 大虾说的库没有找到。。。。。失败
tb01412(tb) 说人为调换,对于整形时可以的,但是对于浮点型我要验证下看
tb01412
2006-04-29
打赏
举报
回复
1.用紧凑格式的结构体定义
2.将每个非char类型的成员取出后转成网络字节序然后再发送出去
3.接收到之后将先存临时的结构体中,将所有非CHAR类型的成员转换成本地字节序
只要是一个字节以上的数据结构,都存在字节序的问题,为了简化处理,有一个笨办法,就是将每个非char类型的成员拷到临时变量中,然后再取这个变量地址,如果是PC机,也就是小端字节序,网络是大端字节序,只需操作这个内存地址,将这个内存地址中的数据按char类型调个头,就OK了,接收端在收到后就执行相反的操作,这就是人为地进行字节序转换,无论是整型,浮点型还是其它类型的转换过程都是一样
字节序
与比特序详解
本文深入探讨了
字节序
的概念,包括大端与小端的区别、各种系统中的
字节序
实现,以及
字节序
与比特序的关系。此外还讨论了
网络
协议、编译器和
结构体
位域中的
字节序
问题
。
轻松理解硬件逻辑
字节序
和软件
字节序
本文详细介绍了
字节序
在软硬件交互中的不同表现,大端和小端模式的区别,并通过实例解析了在
网络
报文和控制报文中如何处理
字节序
问题
。对于大端
字节序
,软硬件
结构体
需反序;而对于小端
字节序
,硬件接口
字节序
不变,但
结构体
需要转置。
字节序
详解
本文详细解释了
字节序
的概念,包括大端序和小端序的定义及其在内存中的存储方式。重点讨论了
字节序
在
网络
编程中的重要性,特别是不同主机间交换二进制数据时可能遇到的
问题
。介绍了
网络
字节序
(Network Byte Order)作为解决方案,并详细说明了如何在编程中进行主机
字节序
与
网络
字节序
之间的转换。最后,强调了在处理
结构体
和浮点数时需要注意的
字节序
问题
,并提供了调试和验证的方法。
结构体
与字符数组相互转换
本文介绍了如何将
结构体
与字符数组进行互相转换的方法,并讨论了在
网络
编程中发送
结构体
数据时需要注意的
问题
,如
字节序
和对齐方式等。
网络
编程-
网络
字节序
本文详细解释了
字节序
的概念,包括大端序和小端序,并阐述了
网络
字节序
的重要性及其在解决不同CPU保存数据方式差异中的作用。除了向sockaddr_in
结构体
变量填充数据外,文章指出在其他情况下无需特别考虑
字节序
问题
。
Linux/Unix社区
23,223
社区成员
74,536
社区内容
发帖
与我相关
我的任务
Linux/Unix社区
Linux/Unix社区 应用程序开发区
复制链接
扫一扫
分享
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章