我想请你的建议。 我需要使用tcp客户端/服务器实现一些协议。它有几个消息,其中一些具有奇数个字节,例如:
typedef struct _msg1
{
unsigned short opcode
unsigned char value
}msg1;
您认为实现它的最佳方式是什么,以避免字节排序问题。 我想到了以下原则:
在从/向struct读取/写入时使用htons / htonl,例如:
mymsg1.opcode = htons(0x1234);
mymsg1.value = 0x56;
有些messeges更难看,例如下面的字节数在运行时之前是未知的,我仍然不确定将其定义为发送的最佳方式。
typedef struct _msg_errors
{
unsigned short opcode
unsigned char errortable[DEPENDS_ON_NUMBER_OF_REAL_ERRORS]
}msg_errors;
谢谢,Ran
答案 0 :(得分:0)
我倾向于避免"叠加演员"作为阅读结构化数据的一种手段。如果性能不重要,那么定义以下方法可能会有所帮助:
int getBE16(uint8_t **p) { // Big-endian 16-bit
uint8_t *pp = *p;
int result = pp[0]*256 + pp[1];
(*p)+=2;
}
int getLE16(uint8_t **p) { // Little-endian 16-bit
uint8_t *pp = *p;
int result = pp[0] + 256*pp[1];
(*p)+=2;
}
int getBE32(uint8_t **p) { // Big-endian 32-bit
uint8_t *pp = *p;
int result = ((pp[0]*256 + pp[1])*256 + pp[2])*256 + pp[3];
(*p)+=4;
}
int getLE32(uint8_t **p) { // Little-endian 16-bit
uint8_t *pp = *p;
int result = pp[0] + 256*(pp[1] + 256*(pp[2] + 256*pp[3]));
(*p)+=4;
}
给定一个数组uint8_t dat[6]
和一个由8位值,一个16位小端值和一个32位大值组成的结构,然后写一个:
uint8_t *p = dat;
mystruct.theByte = *p++;
mystruct.theHalfword = getLE16(&p);
mystruct.theWord = getBE32(&p);
上述代码将是可移植的,与字节顺序无关。如果可以消除函数调用和指针运算会更好,但是消除这些将需要显式指定数据结构中每个字段的偏移量,或者使用一些非常icky的宏来执行此操作。