




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux网络编程-多字节数据的收发.txt珍惜生活上帝还让你活着,就肯定有他的安排。雷锋做了好事不留名,但是每一件事情都记到日记里面。Linux网络编程一步一步学-多字节数据的收发首先,必须说明的是网络上的数据是流式传送的,也就是经常说的stream,流式传送的特点就是一方发送的是1234四个字节,那么接收端收到的必然是1234四个字节,顺序完全相同。其次,必须说明的是主机字节序,不同CPU保存数据的方式不同,即高位在前还是低位在前的问题的,大家可以自己google搜索一下“big little endian CPU”会发现很多人解释这个问题。对于单个字节的数据,即存储空间占用1Byte的数据,没有任何问题,但由于数据很大,通常1Byte表示不了,就必须引入多字节表示的数据,比如一个int通常为32个bit的数据,即4Byte表示一个int,那么当你定义一个int型变量x时,它的值可能是0x1234,即x=0x1234;但如果是另外一种顺序,则x=0x4321,显然这两个数相差很大。big-endian和little-endian问题简单说来就是对于同样的4个字节1234,一种顺序表示为1234,另一种顺序可能表示为4321。这就象中文表示姓名和英文表示姓名的顺序不一样,中国人姓名表示时姓在前名在后,而英文习惯里表示姓名时名在前姓在后,对于汉语的zhou lifa,英文里可能写成lifa zhou。如果双方不知道这个差别,英文习惯的人听汉语的人说人名zhou lifa里必然以为是姓lifa的叫zhou的人。你可以用这个程序来测试你的主机字节序:#include #include int main(void) printf(big:%d little:%d mine:%dn, _BIG_ENDIAN, _LITTLE_ENDIAN, _BYTE_ORDER); return 0; 因此,基于上述两点我们就明白了“多字节数据传送必须要关注数据顺序”。对于单字节的数据,比如char型的,没有问题,所以在前面所有例子程序中,一个程序发送“hello, Linux”,另一个程序必然同样收到这样的字符串而不会顺序乱了。但如果你在这边发过去四个字节1234表示一个int数据,对方接收到以后不知道你的机器是big-endian还是little-endian,按照它自己的理解来解释这个数字,可能这个数字就是4321了。好在前人已经想到这个问题了,因此网络编程基础“TCP/IP协议”里已经规定所有在网络上传送的数据统一采用big-endian顺序。因此,正确的网络编程方法是这样的:如果你要发送纯字符串给对方,那么相当容易,可以这样:char buf = This is a test string;.ret = send(socket_fd, buf, strlen(buf), 0);. 如果你要发送多字节数据,比如short,int,float,double,long你必须先转换为big-endian序再发送,比如:int age = 30;age = htonl(age);ret = send(socket_fd, (void *)&age, sizeof(int), 0); 这里涉及一些网络字节序和主机字节序转换的函数,把主机(host)字节序转换为网络(network)字节序用到htons,htonl等函数,反之则用ntohs,ntohl等函数。man一下就知道这几个函数的用处和用法了。对于结构数据的传送比如有这样一个表示人员信息的结构:struct member char name32; int age; char gender; char address128; 当你定义了一个变量struct member personalInfo并把personalInfo的各字段内容准备好了,如何把这个信息发送给对方呢?一种方法:发送和接收的双方都知道上述结构struct member的定义,因此,不管一个人的名字是几个字节,也不管这个人的住址信息是多少个字节,发送的一方可以这样写程序:struct member personalInfo;.ret = send(socket_fd, personalI, 32, 0);.personalInfo.age = htonl(personalInfo.age);ret = send(socket_fd, (void *)&personalInfo.age, sizeof(int), 0);.ret = send(socket_fd, &personalInfo.gender, sizeof(char), 0);.ret = send(socket_fd, personalInfo.address, 128, 0);. 而接收一方则可以这样写程序:struct member personalInfo;.ret = recv(socket_fd, personalI, 32, 0);.ret = recv(socket_fd, (void *)&personalInfo.age, sizeof(int), 0);personalInfo.age = ntohl(personalInfo.age);.ret = recv(socket_fd, &personalInfo.gender, sizeof(char), 0);.ret = recv(socket_fd, personalInfo.address, 128, 0);. 当然,这样写程序的前提仍然是双方是32位或64位系统,如果一方是32位系统,他这里表示的sizeof(int)是32bit个字节,而另一方表示的是64bit,程序工作会有问题的。另一种方法:发送方这样写程序:#pragma pack(1) /* 这一行应在定义struct member时写 */struct member personalInfo;.personalInfo.age = htonl(personalInfo.age);ret = send(socket_fd, (void *)&personalInfo, sizeof(struct member), 0);. 接收方这样写程序:#pragma pack(1) /* 这一行应在定义struct member时写,不一定要写成1,关键是要与发送方的定义保持一致 */struct member personalInfo;.ret = recv(socket_fd, (void *)&personalInfo, sizeof(struct member), 0);personalInfo.age = ntohl(personalInfo.age);. 这种方法要注意的是双方有个一致的定义pack(1)即,按位对齐方式定义相同。在网上搜索“C pragma pack”会发现很多这样的讨论。当然也可以试试这几段代码的结果:#include #pragma pack(1)int main(void)struct member char name32; int age; char gender; char address128;printf(size is:%dn, sizeof(struct member);return 0; #include #pragma pack(2)int main(void)struct member char name32;int age;char gender;char address128;printf(size is:%dn, sizeof(struct member);return 0; #include #pragma pack(3)int main(void)struct member char name32;int age;char gender;char address128;printf(size is:%dn, sizeof(struct member);return 0; #include #pragma pack(4)int main(void)struct member char name32;int age;char gender;char address128;printf(size is:%dn, sizeof(struct member);return 0; #include #pragma pack(5)int main(void)struct member char name32;int age;char gender;char address128;printf(size is:%dn, sizeof(struct member);return 0; #include #pragma pack(6)int main(void)struct member char name32;int age;char gender;char address128;printf(size is:%dn, sizeof(struct member);return 0; #include #pragma pack(7)int main(void)struct member char name32;int age;char gender;char address1
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025畜牧饲养管理合同模板
- 2025版权授权全案打包合作合同模板
- 第十二课 班级美食展说课稿-2025-2026学年小学信息技术(信息科技)六年级下册教科版(云南)
- 2025上海标准的公租房买卖合同
- 黑龙江公务员考试真题2025
- 2025智能解决方案代理合同专业版(合同版本)
- 1.2同位角、内错教、同旁内角 说课稿- -2024-2025学年浙教版数学七年级下册
- 2025安心食品供应链合同
- 2025中外专有技术许可合同合同学堂
- 机械厂工伤医疗救治规定
- 咖啡基础培训课件
- 人才服务合同书
- 2025年工会财务大赛理论题库(附答案)
- 2025-2026学年统编版八年级上册道德与法治教学计划含教学进度表
- 矿井顶板事故防治课件
- 小学数学西南师大四年级上册二加减法的关系和加法运算律《减法的运算性质》教学设计
- 通信光缆线路工程安全技术交底大全
- 购牛合同参考参考
- 纳迪亚之宝全流程攻略 100%完结完整通关指南
- 第四讲政府间关系
- GB 30678-2014 客车用安全标志和信息符号(高清版)
评论
0/150
提交评论