微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

字节分配

我在编写networking软件时面临一些问题。 当我尝试发送或接收包含8字节数据types的结构时,下一个发送或接收的结构会受到某种程度的影响。 我有几件事情,但首先我想在debugging之前确认一件事情。 我在64位x-86系统上使用32位Ubuntu 11.04(愚蠢的我)。 这是否与字节alignment问题有关?

我正在开发一个控制器来与Open Flow开关进行通信。 openflow协议定义了基于哪些交换机构build的一组规格。 问题是当我尝试与交换机进行通信时,一切正常,直到我发送或接收包含64位datetypes(uint64_t)的结构。 用于发送和接收function的特定结构是

estruct ofp_header { uint8_t version; /* OFP_VERSION. */ uint8_t type; /* One of the OFPT_ constants. */ uint16_t length; /* Length including this ofp_header. */ uint32_t xid; /* Transaction id associated with this packet. Replies use the same id as was in the request to facilitate pairing. */}; assert(sizeof(struct ofp_header) == 8); /* Switch features. */ struct ofp_switch_features { struct ofp_header header; uint64_t datapath_id; /* Datapath unique ID. The lower 48-bits are for a MAC address,while the upper 16-bits are implementer-defined. */ uint32_t n_buffers; /* Max packets buffered at once. */ uint8_t n_tables; /* Number of tables supported by datapath. */ uint8_t pad[3]; /* Align to 64-bits. */ /* Features. */ /* Bitmap of support "ofp_capabilities". */ uint32_t capabilities; /* Bitmap of supported "ofp_action_type"s. */ uint32_t actions; /* Port info.*/ struct ofp_phy_port ports[0]; /* Port deFinitions. The number of ports is inferred from the length field in the header. */ }; assert(sizeof(struct ofp_switch_features) == 32);

问题是当我使用任何其他数据types小于64位的结构进行通信时,一切正常。 当我收到function回复显示正确的值,但之后,如果我收到任何其他结构它显示垃圾值。 即使我收到function回复我得到垃圾值。 简而言之,如果在代码的任何一点我收到的function请求或规格中定义的数据types为64位的任何其他结构,下一个结构会收到垃圾值。 用于发送和接收function请求的代码如下

////// features request and reply //////////// ofp_header features_req; features_req.version=OFP_VERSION; features_req.type=OFPT_FEATURES_REQUEST; features_req.length= htons(sizeof features_req); features_req.xid = htonl(rcv_hello.xid); if (send(connected,&features_req,sizeof(features_req),0)==-1) { printf("Error in sending messagen"); exit(-1); } printf("features req sent!n"); ofp_switch_features features_rep={0}; if (recv(connected,&features_rep,sizeof(features_rep),0)==-1) { printf("Error in receiving messagen"); exit(-1); } printf("message type : %dn",features_rep.header.type); printf("version : %dn",features_rep.header.version); printf("message length: %dn",ntohs(features_rep.header.length)); printf("xid : %dn",ntohl(features_rep.header.xid)); printf("buffers: %dn",ntohl(features_rep.n_buffers)); printf("tables: %dn",features_rep.n_tables);

谢谢,阿卜杜拉

multithreading文件传输与套接

OS X getsockopt:不是SO_PROTOCOL

为什么gethostbyname和gethostbyaddr被认为是过时的?

为什么不能将linux服务绑定到环回?

Linux套接字内核缓冲区是否交换到磁盘?

套接错误:连接被拒绝 – 我在做什么错?

有没有办法让UDP .net套接字在套接字closures时释放绑定端口?

EAGAIN错误接受阻塞套接

在Python 3中给出一个套接字和inode的进程ID

仅启用来自指定IP地址的传入连接

在发送它们之前将你的结构转换成一个字符数组 – 这是调用序列化

使用函数系列等来确保整数按网络顺序发送。 节省各种机器的endians麻烦

一个接收端读取字节并重建结构。

这将确保你不会有任何麻烦。

我得到了Daniweb.com的帮助,所有的荣誉都归功于一个拥有尼克松(nickz)的家伙。 他的回答是 ,我引用:

这个问题与64位类型无关。 你读的值不是垃圾,而是非常有价值的端口定义:

struct ofp_phy_port ports[0]; /* Port deFinitions. The number of ports is inferred from the length field in the header. */

这意味着,一旦你

recv(connected,0)

你需要检查features_rep.header.length,找出p_phy_port后面有多少个结构,为它们分配内存并读取这些数据。

我这样做,并感谢他,我的问题解决了,一切顺利:)对于每个人回答。 欢呼:)

你甚至可以考虑使用序列化技术:也许JSON , XDR , YAML可能是相关的。 或像s11n , jansson等图书馆

这是什么是想要的

features_req.version=OFP_VERSION; features_req.type=OFPT_FEATURES_REQUEST; features_req.length= htons(sizeof features_req); features_req.xid = htonl(rcv_hello.xid); char data[8]; data[0] = features_req.version; data[1] = features_req.type; memcpy(data + 2,&features_req.length,2); memcpy(data + 4,&features_req.xid,4); if (send(connected,data,8) ....

在收到结束

char data[8]; if (recv(conncted,8) ... features_req.version = data[0]; features_req.type = data[1]; memcpy(&features_req.length,data + 2,2); memcpy(&features_req.xid,data + 4,4); features_req.length = ntohs(features_req.length); features_req.xid= ntohl(features_req.xid);

1如果你坚持发送结构,你应该确保它们是字节对齐的。

为此,请使用像这样的编译pack :

#pragma pack(1) struct mystruct{ uint8_t myint8; uint16_t myint16; }; #pragma pack()

这样做可以确保此结构仅使用3个字节。

2为了从主机顺序转换64位值到网络顺序这篇文章阅读interessing: 是否有任何“标准”htonl样函数为64位整数在C + +? (不,它只以c ++开头,也以C结尾)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐