2 Bytes for Message::Length is enough

This commit is contained in:
Stone 2015-11-30 02:18:49 +00:00
parent f9dcb50e6f
commit bb223db504
3 changed files with 39 additions and 50 deletions

View File

@ -11,7 +11,7 @@ public:
byte Code; // 消息代码 byte Code; // 消息代码
byte Reply:1; // 是否响应指令 byte Reply:1; // 是否响应指令
byte Error:1; // 是否错误 byte Error:1; // 是否错误
uint Length; // 数据长度 ushort Length; // 数据长度
byte* Data; // 数据。指向子类内部声明的缓冲区 byte* Data; // 数据。指向子类内部声明的缓冲区
void* State; // 其它状态数据 void* State; // 其它状态数据

View File

@ -58,16 +58,17 @@ bool TinyMessage::Read(Stream& ms)
if(Dest == Src) return false; if(Dest == Src) return false;
// 校验剩余长度 // 校验剩余长度
if(ms.Remain() < Length + 2) return false; ushort len = Length;
if(ms.Remain() < len + 2) return false;
// 避免错误指令超长,导致溢出 // 避免错误指令超长,导致溢出
if(Data == _Data && Length > ArrayLength(_Data)) if(Data == _Data && len > ArrayLength(_Data))
{ {
debug_printf("错误指令,长度 %d 大于消息数据缓冲区长度 %d \r\n", Length, ArrayLength(_Data)); debug_printf("错误指令,长度 %d 大于消息数据缓冲区长度 %d \r\n", len, ArrayLength(_Data));
//assert_param(false); //assert_param(false);
return false; return false;
} }
if(Length > 0) ms.Read(Data, 0, Length); if(len > 0) ms.Read(Data, 0, len);
// 读取真正的校验码 // 读取真正的校验码
Checksum = ms.ReadUInt16(); Checksum = ms.ReadUInt16();
@ -94,25 +95,26 @@ void TinyMessage::Write(Stream& ms) const
TS("TinyMessage::Write"); TS("TinyMessage::Write");
ushort len = Length;
// 实际数据拷贝到占位符 // 实际数据拷贝到占位符
TinyMessage* p = (TinyMessage*)this; auto p = (TinyMessage*)this;
p->_Code = Code; p->_Code = Code;
p->_Length = Length; p->_Length = len;
p->_Reply = Reply; p->_Reply = Reply;
p->_Error = Error; p->_Error = Error;
byte* buf = ms.Current(); auto buf = ms.Current();
// 不要写入验证码 // 不要写入验证码
ms.Write((byte*)&Dest, 0, HeaderSize); ms.Write(&Dest, 0, HeaderSize);
if(Length > 0) ms.Write(Data, 0, Length); if(len > 0) ms.Write(Data, 0, len);
// 计算Crc之前需要清零TTL和Retry // 计算Crc之前需要清零TTL和Retry
byte fs = buf[3]; byte fs = buf[3];
TFlags* f = (TFlags*)&buf[3]; auto f = (TFlags*)&buf[3];
f->TTL = 0; f->TTL = 0;
f->Retry = 0; f->Retry = 0;
p->Checksum = p->Crc = Crc::Hash16(Array(buf, HeaderSize + Length)); p->Checksum = p->Crc = Crc::Hash16(Array(buf, HeaderSize + len));
// 还原数据 // 还原数据
buf[3] = fs; buf[3] = fs;
@ -165,11 +167,12 @@ void TinyMessage::Show() const
#if MSG_DEBUG #if MSG_DEBUG
assert_ptr(this); assert_ptr(this);
msg_printf("0x%02X => 0x%02X Code=0x%02X Flag=0x%02X Seq=0x%02X Retry=%d", Src, Dest, Code, *((byte*)&_Code+1), Sequence, Retry); msg_printf("0x%02X => 0x%02X Code=0x%02X Flag=0x%02X Seq=0x%02X Retry=%d", Src, Dest, Code, *((byte*)&_Code+1), Sequence, Retry);
if(Length > 0) ushort len = Length;
if(len > 0)
{ {
assert_ptr(Data); assert_ptr(Data);
msg_printf(" Data[%d]=", Length); msg_printf(" Data[%d]=", len);
ByteArray(Data, Length).Show(); ByteArray(Data, len).Show();
} }
if(Checksum != Crc) msg_printf(" Crc Error 0x%04x [%04X]", Crc, __REV16(Crc)); if(Checksum != Crc) msg_printf(" Crc Error 0x%04x [%04X]", Crc, __REV16(Crc));
msg_printf("\r\n"); msg_printf("\r\n");
@ -660,10 +663,10 @@ void TinyController::ShowStat()
void MessageNode::SetMessage(TinyMessage& msg) void MessageNode::SetMessage(TinyMessage& msg)
{ {
Sequence = msg.Sequence; Sequence = msg.Sequence;
Period = 0; Period = 0;
Times = 0; Times = 0;
LastSend = 0; LastSend = 0;
// 注意此时指针位于0而内容长度为缓冲区长度 // 注意此时指针位于0而内容长度为缓冲区长度
Stream ms(Data, ArrayLength(Data)); Stream ms(Data, ArrayLength(Data));

View File

@ -30,25 +30,20 @@ bool TokenMessage::Read(Stream& ms)
Code = temp & 0x3f; Code = temp & 0x3f;
Reply = temp >> 7; Reply = temp >> 7;
Error = (temp >> 6) & 0x01; Error = (temp >> 6) & 0x01;
Length = ms.ReadByte(); //Length = ms.ReadByte();
ushort len = ms.ReadEncodeInt();
Length = len;
// 占位符拷贝到实际数据 if(ms.Remain() < len) return false;
/*Code = _Code;
Length = _Length;
Reply = _Reply;
Error = _Error;*/
if(ms.Remain() < Length) return false;
//assert_param2(Data != _Data || Length <= ArrayLength(_Data), "令牌消息太大,缓冲区无法放下");
// 避免错误指令超长,导致溢出 // 避免错误指令超长,导致溢出
if(Data == _Data && Length > ArrayLength(_Data)) if(Data == _Data && len > ArrayLength(_Data))
{ {
debug_printf("错误指令,长度 %d 大于消息数据缓冲区长度 %d \r\n", Length, ArrayLength(_Data)); debug_printf("错误指令,长度 %d 大于消息数据缓冲区长度 %d \r\n", len, ArrayLength(_Data));
//assert_param(false); //assert_param(false);
return false; return false;
} }
if(Length > 0) ms.Read(Data, 0, Length); if(len > 0) ms.Read(Data, 0, len);
return true; return true;
} }
@ -58,17 +53,6 @@ void TokenMessage::Write(Stream& ms) const
{ {
assert_ptr(this); assert_ptr(this);
// 实际数据拷贝到占位符
/*TokenMessage* p = (TokenMessage*)this;
p->_Code = Code;
p->_Reply = Reply;
p->_Error = Error;
p->_Length = Length;
byte tmp = _Code | (_Reply << 7) | (_Error << 6);
ms.Write(tmp);
ms.Write(_Length);*/
byte tmp = Code | (Reply << 7) | (Error << 6); byte tmp = Code | (Reply << 7) | (Error << 6);
ms.Write(tmp); ms.Write(tmp);
@ -76,8 +60,9 @@ void TokenMessage::Write(Stream& ms) const
ms.Write((byte)0); ms.Write((byte)0);
else else
{ {
ms.WriteEncodeInt(Length); ushort len = Length;
if(Length > 0) ms.Write(Data, 0, Length); ms.WriteEncodeInt(len);
if(len > 0) ms.Write(Data, 0, len);
} }
} }
@ -130,13 +115,14 @@ void TokenMessage::Show() const
debug_printf(" _Code=0x%02X", Code); debug_printf(" _Code=0x%02X", Code);
} }
if(Length > 0) ushort len = Length;
if(len > 0)
{ {
assert_ptr(Data); assert_ptr(Data);
debug_printf(" Data[%d]=", Length); debug_printf(" Data[%d]=", len);
// 大于32字节时反正都要换行显示干脆一开始就换行让它对齐 // 大于32字节时反正都要换行显示干脆一开始就换行让它对齐
if(Length > 32) debug_printf("\r\n"); if(len > 32) debug_printf("\r\n");
ByteArray(Data, Length).Show(); ByteArray(Data, len).Show();
} }
debug_printf("\r\n"); debug_printf("\r\n");
#endif #endif
@ -233,8 +219,8 @@ bool TokenController::Valid(const Message& msg)
// 合法来源验证,暂时验证云平台,其它连接将来验证 // 合法来源验证,暂时验证云平台,其它连接将来验证
if(Server) if(Server)
{ {
IPEndPoint* svr = (IPEndPoint*)Server; auto svr = (IPEndPoint*)Server;
IPEndPoint* rmt = (IPEndPoint*)msg.State; auto rmt = (IPEndPoint*)msg.State;
if(!rmt || *svr != *rmt) if(!rmt || *svr != *rmt)
{ {