Chinaunix

标题: socket 中如何获取二进制数据 [打印本页]

作者: liunxcu    时间: 2010-12-27 22:37
标题: socket 中如何获取二进制数据
如题,加入有数据为二进制格式,顺序为:header(short):contents(int):tail(short)..., 通过socket通信获得了此数据,
请问该如何解析呢?
1:用char 数组解析?
2:设一数据结构为
  1. typedef struct {
  2. unsigned short header;
  3. unsigned int  contents;
  4. unsigned short tail;
  5. } msg;
  6. ...
  7. msg *pmsg;
  8. pmsg = (msg *)malloc(sizeof(msg));
  9. memcpy(pmsg, &source ,sizeof(msg));
复制代码
获取数据对象?
不知哪个靠谱啊,请高人指点。{:3_200:}
作者: evaspring    时间: 2010-12-28 00:36
就是这样 !
作者: hellioncu    时间: 2010-12-28 08:41
不用memcpy,指针强制转换下就可以了
作者: xiaobenniao514    时间: 2010-12-28 08:59
传sizeof(msg)大小的串过去就可以了,那边再把这串类型强制转成msg类型。
或者发送端进行序列化,接收端再反序列化。就像java的序列化,我是这样理解的,不知道对不对。
作者: liunxcu    时间: 2010-12-28 09:36
回复 2# evaspring
那么,如果我用 CHAR 数组一个字节一个字节的接受呢,而不是按发送方的数据格式,是否会出现数据错位呢?
  1. typedef struct {
  2. int header;
  3. unsigned short contents;
  4. unsigned short tail;
  5. } send_data;

  6. typedef struct {
  7. char data[8];
  8. } recv_data;

  9. int main()
  10. {
  11. ...
  12. recv_data *rd;
  13. rd = (recv_data *)malloc(sizeof(recv_data));
  14. memcpy(recv_data, &data, sizeof(recv_data));
  15. ...

  16. }
复制代码
是否会出现字节排序错乱的情况?
作者: liunxcu    时间: 2010-12-28 09:51
回复 3# hellioncu
  1.         // Get the header, and check command
  2.         memcpy(buf, line.c_str(), sizeof(GK301_header) + sizeof(GK301_login) + sizeof(GK301_tail));
  3.         GK301_login *glg;
  4.         glg = (GK301_login *)malloc(sizeof(GK301_login));
  5.         memcpy(glg, buf + sizeof(GK301_header), sizeof(GK301_login));
  6.         printf("ID=%x%x%x%x%x%x%x%x, Rec=0x%x\n", glg->id[0], glg->id[1], glg->id[2],glg->id[3],
  7.                 glg->id[4],glg->id[5],glg->id[6],glg->id[7],glg->id_num);
  8.         // Get the tail, may be we need the serial number
  9.         GK301_tail *gtl;
  10.         gtl = (GK301_tail *)malloc(sizeof(GK301_tail));
  11.         memcpy(gtl, buf + sizeof(GK301_header) + sizeof(GK301_login), sizeof(GK301_tail));
  12.         printf("Serial=0x%x, CRC=0x%x, Stop=0x%x\n", gtl->seq, gtl->crc, gtl->stop);

  13.         // At last, we should reply a package to the terminal device
  14.         bzero(buf, sizeof(buf));
  15.         memcpy(buf, line.c_str(), sizeof(GK301_header));
  16.         memcpy(buf + sizeof(GK301_header), gtl, sizeof(GK301_tail));
  17.         result = buf;
复制代码
那么请看以上的代码,我的处理有问题吗,无法获得我想要的数据啊,只能获得部分数据。

作者: liunxcu    时间: 2010-12-28 09:53
回复 4# xiaobenniao514
可是接受的数据却不尽人意啊,
作者: id_for_fun    时间: 2010-12-28 09:56
网路通信要注意字节序。来回都转换一下
作者: hellioncu    时间: 2010-12-28 10:25
回复  hellioncu 那么请看以上的代码,我的处理有问题吗,无法获得我想要的数据啊,只能获得部分数据。
:e ...
liunxcu 发表于 2010-12-28 09:51



    先保证line中的数据是完整的
作者: aobai    时间: 2010-12-28 10:55
关注
作者: liunxcu    时间: 2010-12-28 11:08
回复 8# id_for_fun
那该如何调整循序呢?
作者: zhanglistar    时间: 2010-12-28 15:14
回复 1# liunxcu


    选择方式1.把所有的数据都当做文本串来传递,这样就不涉及到客户端和服务器的字节序问题。
作者: wb112200    时间: 2010-12-28 17:21
在数据完整的情况下 数据结构互转就可以了 不用去分析传输的是二进制还是其他编码...
另外有个疑问:socket传输的数据不是不存在顺序的问题吗?这种情况不是由TCP来处理的么?
作者: chenzhanyiczy    时间: 2010-12-28 19:42
字节序
作者: folklore    时间: 2010-12-28 22:04
如题,加入有数据为二进制格式,顺序为:header(short):contents(int):tail(short)..., 通过socket通信获得 ...
liunxcu 发表于 2010-12-27 22:37


如果两个通信的机器都是一样的,就无所谓了(包括编译器)
最好的方法是用字节流
这样:
id=0
data=1234
value=4557

当然,这样要先编码再解码


--------------------Over-------------------------------
作者: newroot_phy    时间: 2010-12-28 23:52
字节序
chenzhanyiczy 发表于 2010-12-28 19:42



    正解!

非单字节的数据发送到网络上需要进行转换!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2