发送或接收结构时的字节对齐

Abd*_*lah 0 c c++ sockets linux network-programming

我在编写网络软件时面临一些问题.当我尝试发送或接收包含8字节数据类型的结构时,下一个发送或接收的结构以某种方式受到影响.我有几点想法,但首先我想在进入调试之前确认一件事.我在64位x-86系统上使用32位Ubuntu 11.04(愚蠢的我).这与字节对齐问题有什么关系吗?

我正在开发一个控制器来与Open Flow交换机通信.openflow协议根据构建的交换机定义一组规范.问题是当我尝试与交换机通信时,一切正常,直到我发送或接收包含64位日期类型(uint64_t)的结构.用于发送和接收功能的特定结构是

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);
Run Code Online (Sandbox Code Playgroud)

问题是当我使用任何其他数据类型小于64位的结构进行通信时一切正常.当我收到功能回复时,它显示正确的值但在此之后,如果我收到任何其他结构,它显示垃圾值.即使我再次收到功能回复,我也会得到垃圾值.简而言之,如果在代码的任何一点,我收到功能请求或在规范中定义的具有64位数据类型的任何其他结构,则下一个结构接收垃圾值.用于发送和接收功能请求的代码如下

////// 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 message\n");
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 message\n");
exit(-1);
}

printf("message type : %d\n",features_rep.header.type);
printf("version : %d\n",features_rep.header.version);
printf("message length: %d\n",ntohs(features_rep.header.length));
printf("xid : %d\n",ntohl(features_rep.header.xid));
printf("buffers: %d\n",ntohl(features_rep.n_buffers));
printf("tables: %d\n",features_rep.n_tables);
Run Code Online (Sandbox Code Playgroud)

Ed *_*eal 6

  1. 在发送之前将结构转换为字符数组 - 这是调用序列化
  2. 使用函数族htons等确保以网络顺序发送整数.省去各种机器的端子上的麻烦
  3. 一个接收端读取字节并重构结构.

这将确保您不会有任何麻烦.