数据流Stream去掉读写模版,改用普通读写函数,针对整数进行操作。
模版容易错误识别,并且导致可以直接写入字符串指针等隐含错误。
This commit is contained in:
parent
8feaeaa5c3
commit
d45e8b0886
|
@ -1,5 +1,6 @@
|
|||
#include "W5500.h"
|
||||
#include "Time.h"
|
||||
#include "Task.h"
|
||||
|
||||
#define NET_DEBUG DEBUG
|
||||
|
||||
|
@ -303,7 +304,12 @@ bool W5500::Open()
|
|||
|
||||
//if(!TaskID) TaskID = Sys.AddTask(IRQTask, this, -1, -1, "W5500中断");
|
||||
// 为解决芯片有时候无法接收数据的问题,需要守护任务辅助
|
||||
if(!TaskID) TaskID = Sys.AddTask(IRQTask, this, 0, 1000, "W5500中断");
|
||||
if(!TaskID)
|
||||
{
|
||||
TaskID = Sys.AddTask(IRQTask, this, 0, 1000, "W5500中断");
|
||||
Task* task = Task::Get(TaskID);
|
||||
task->MaxDeepth = 2; // 以太网允许重入,因为有时候在接收里面等待下一次接收
|
||||
}
|
||||
|
||||
Opened = true;
|
||||
|
||||
|
@ -1339,7 +1345,7 @@ void UdpClient::RaiseReceive()
|
|||
ByteArray bs2(6);
|
||||
ms.Read(bs2);
|
||||
|
||||
ushort len = ms.Read<ushort>();
|
||||
ushort len = ms.ReadUInt16();
|
||||
len = __REV16(len);
|
||||
// 数据长度不对可能是数据错位引起的,直接丢弃数据包
|
||||
if(len > 1500)
|
||||
|
|
|
@ -32,18 +32,15 @@ void Message::SetData(const ByteArray& bs, uint offset)
|
|||
|
||||
void Message::SetError(byte errorCode, const char* msg)
|
||||
{
|
||||
/*byte* p = Data;
|
||||
*p++ = errorCode;
|
||||
|
||||
while(msg) *p++ = (byte)*msg++;
|
||||
|
||||
Length = p - Data;*/
|
||||
byte* p = (byte*)msg;
|
||||
uint len = 0;
|
||||
while(*p++) len++;
|
||||
|
||||
Error = true;
|
||||
|
||||
Stream ms(Data, MaxDataSize());
|
||||
ms.Write(errorCode);
|
||||
ms.Write(msg);
|
||||
ms.Write((const byte*)msg, 0, len);
|
||||
|
||||
Length = ms.Position();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ bool Modbus::Read(Stream& ms)
|
|||
Length = ms.Remain() - 2;
|
||||
ms.Read(&Data, 0, Length);
|
||||
|
||||
Crc = ms.Read<ushort>();
|
||||
Crc = ms.ReadUInt16();
|
||||
|
||||
// 直接计算Crc16
|
||||
Crc2 = Sys.Crc16(buf, ms.Position() - p - 2);
|
||||
|
|
12
Net/Dhcp.cpp
12
Net/Dhcp.cpp
|
@ -176,16 +176,16 @@ void Dhcp::PareOption(Stream& ms)
|
|||
{
|
||||
while(ms.Remain())
|
||||
{
|
||||
byte opt = ms.Read<byte>();
|
||||
byte opt = ms.ReadByte();
|
||||
if(opt == DHCP_OPT_End) break;
|
||||
byte len = ms.Read<byte>();
|
||||
byte len = ms.ReadByte();
|
||||
// 有些家用路由器会发送错误的len,大于4字节,导致覆盖前后数据
|
||||
switch(opt)
|
||||
{
|
||||
case DHCP_OPT_Mask: Host->Mask = ms.Read<int>(); len -= 4; break;
|
||||
case DHCP_OPT_DNSServer: Host->DNSServer = ms.Read<int>(); len -= 4; break;
|
||||
case DHCP_OPT_Router: Host->Gateway = ms.Read<int>(); len -= 4; break;
|
||||
case DHCP_OPT_DHCPServer: Host->DHCPServer = ms.Read<int>(); len -= 4; break;
|
||||
case DHCP_OPT_Mask: Host->Mask = ms.ReadUInt32(); len -= 4; break;
|
||||
case DHCP_OPT_DNSServer: Host->DNSServer = ms.ReadUInt32(); len -= 4; break;
|
||||
case DHCP_OPT_Router: Host->Gateway = ms.ReadUInt32(); len -= 4; break;
|
||||
case DHCP_OPT_DHCPServer: Host->DHCPServer= ms.ReadUInt32(); len -= 4; break;
|
||||
//default:
|
||||
// debug_printf("Unkown DHCP Option=%d Length=%d\r\n", opt, len);
|
||||
}
|
||||
|
|
66
Stream.cpp
66
Stream.cpp
|
@ -19,6 +19,7 @@ Stream::Stream(uint len)
|
|||
_Position = 0;
|
||||
Length = len;
|
||||
_canWrite = true;
|
||||
Little = true;
|
||||
}
|
||||
|
||||
// 使用缓冲区初始化数据流。注意,此时指针位于0,而内容长度为缓冲区长度
|
||||
|
@ -33,6 +34,7 @@ Stream::Stream(byte* buf, uint len)
|
|||
_needFree = false;
|
||||
_canWrite = true;
|
||||
Length = len;
|
||||
Little = true;
|
||||
}
|
||||
|
||||
Stream::Stream(const byte* buf, uint len)
|
||||
|
@ -45,6 +47,7 @@ Stream::Stream(const byte* buf, uint len)
|
|||
_needFree = false;
|
||||
_canWrite = false;
|
||||
Length = len;
|
||||
Little = true;
|
||||
}
|
||||
|
||||
// 使用字节数组初始化数据流。注意,此时指针位于0,而内容长度为缓冲区长度
|
||||
|
@ -56,6 +59,7 @@ Stream::Stream(ByteArray& bs)
|
|||
_needFree = false;
|
||||
_canWrite = true;
|
||||
Length = bs.Length();
|
||||
Little = true;
|
||||
}
|
||||
|
||||
Stream::Stream(const ByteArray& bs)
|
||||
|
@ -66,6 +70,7 @@ Stream::Stream(const ByteArray& bs)
|
|||
_needFree = false;
|
||||
_canWrite = false;
|
||||
Length = bs.Length();
|
||||
Little = true;
|
||||
}
|
||||
|
||||
// 销毁数据流
|
||||
|
@ -147,7 +152,7 @@ uint Stream::ReadEncodeInt()
|
|||
byte temp = 0;
|
||||
for(int i = 0, k = 0; i < 4; i++, k += 7)
|
||||
{
|
||||
temp = Read<byte>();
|
||||
temp = ReadByte();
|
||||
if(temp < 0x7F)
|
||||
{
|
||||
value |= (temp << k);
|
||||
|
@ -350,3 +355,62 @@ bool Stream::WriteString(const String& str)
|
|||
ByteArray bs(str);
|
||||
return WriteArray(bs);
|
||||
}
|
||||
|
||||
byte Stream::ReadByte()
|
||||
{
|
||||
byte* p = Current();
|
||||
if(!Seek(1)) return 0;
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
ushort Stream::ReadUInt16()
|
||||
{
|
||||
byte* p = ReadBytes(2);
|
||||
ushort v = *(ushort*)p;
|
||||
if(!Little) v = __REV16(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
uint Stream::ReadUInt32()
|
||||
{
|
||||
byte* p = ReadBytes(4);
|
||||
uint v = *(uint*)p;
|
||||
if(!Little) v = __REV(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
ulong Stream::ReadUInt64()
|
||||
{
|
||||
byte* p = ReadBytes(8);
|
||||
ulong v = *(ulong*)p;
|
||||
if(!Little) v = __REV(v >> 32) | ((ulong)__REV(v & 0xFFFFFFFF) << 32);
|
||||
return v;
|
||||
}
|
||||
|
||||
bool Stream::Write(byte value)
|
||||
{
|
||||
return Write((byte*)&value, 0, 1);
|
||||
}
|
||||
|
||||
bool Stream::Write(ushort value)
|
||||
{
|
||||
if(!Little) value = __REV16(value);
|
||||
|
||||
return Write((byte*)&value, 0, 2);
|
||||
}
|
||||
|
||||
bool Stream::Write(uint value)
|
||||
{
|
||||
if(!Little) value = __REV(value);
|
||||
|
||||
return Write((byte*)&value, 0, 4);
|
||||
}
|
||||
|
||||
bool Stream::Write(ulong value)
|
||||
{
|
||||
if(!Little) value = __REV(value >> 32) | ((ulong)__REV(value & 0xFFFFFFFF) << 32);
|
||||
|
||||
return Write((byte*)&value, 0, 8);
|
||||
}
|
||||
|
||||
|
|
23
Stream.h
23
Stream.h
|
@ -11,14 +11,14 @@ class Stream
|
|||
private:
|
||||
byte* _Buffer; // 数据缓冲区。扩容后会重新分配缓冲区
|
||||
uint _Capacity; // 缓冲区容量
|
||||
bool _needFree; // 是否自动释放
|
||||
bool _canWrite; // 是否可写
|
||||
// 又是头疼的对齐问题
|
||||
ushort _Reserved;
|
||||
uint _Position; // 游标位置
|
||||
|
||||
byte _Arr[64]; // 内部缓冲区。较小内存需要时,直接使用栈分配,提高性能。
|
||||
|
||||
bool _needFree; // 是否自动释放
|
||||
bool _canWrite; // 是否可写
|
||||
public:
|
||||
bool Little; // 默认小字节序。仅影响数据读写操作
|
||||
uint Length; // 数据长度
|
||||
|
||||
// 分配指定大小的数据流
|
||||
|
@ -78,6 +78,16 @@ public:
|
|||
// 把字符串作为变长数据写入到数据流。以压缩整数开头表示长度
|
||||
bool WriteString(const String& str);
|
||||
|
||||
byte ReadByte();
|
||||
ushort ReadUInt16();
|
||||
uint ReadUInt32();
|
||||
ulong ReadUInt64();
|
||||
|
||||
bool Write(byte value);
|
||||
bool Write(ushort value);
|
||||
bool Write(uint value);
|
||||
bool Write(ulong value);
|
||||
|
||||
// 取回指定结构体指针,并移动游标位置
|
||||
template<typename T>
|
||||
T* Retrieve(bool move = true)
|
||||
|
@ -92,7 +102,7 @@ public:
|
|||
return pt;
|
||||
}
|
||||
|
||||
// 常用读写整数方法
|
||||
/*// 常用读写整数方法
|
||||
template<typename T>
|
||||
T Read()
|
||||
{
|
||||
|
@ -112,6 +122,7 @@ public:
|
|||
template<typename T>
|
||||
bool Write(T value)
|
||||
{
|
||||
if(!_canWrite) return false;
|
||||
if(!CheckRemain(sizeof(T))) return false;
|
||||
|
||||
byte* p = Current();
|
||||
|
@ -127,7 +138,7 @@ public:
|
|||
if(_Position > Length) Length = _Position;
|
||||
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
// 读取指定长度的数据并返回首字节指针,移动数据流位置
|
||||
byte* ReadBytes(int count = -1);
|
||||
|
|
|
@ -33,13 +33,13 @@ void Device::Write(Stream& ms) const
|
|||
|
||||
void Device::Read(Stream& ms)
|
||||
{
|
||||
Address = ms.Read<byte>();
|
||||
Kind = ms.Read<ushort>();
|
||||
Address = ms.ReadByte();
|
||||
Kind = ms.ReadUInt16();
|
||||
//ms.ReadArray(HardID);
|
||||
HardID = ms.ReadArray();
|
||||
LastTime= ms.Read<ulong>();
|
||||
DataSize = ms.Read<byte>();
|
||||
ConfigSize = ms.Read<byte>();
|
||||
LastTime= ms.ReadUInt64();
|
||||
DataSize = ms.ReadByte();
|
||||
ConfigSize = ms.ReadByte();
|
||||
Name = ms.ReadString();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,15 +14,15 @@ bool DiscoverMessage::Read(Stream& ms)
|
|||
{
|
||||
if(!Reply)
|
||||
{
|
||||
Type = ms.Read<ushort>();
|
||||
Type = ms.ReadUInt16();
|
||||
HardID = ms.ReadArray();
|
||||
Version = ms.Read<ushort>();
|
||||
Switchs = ms.Read<byte>();
|
||||
Analogs = ms.Read<byte>();
|
||||
Version = ms.ReadUInt16();
|
||||
Switchs = ms.ReadByte();
|
||||
Analogs = ms.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = ms.Read<byte>();
|
||||
Address = ms.ReadByte();
|
||||
Pass = ms.ReadArray();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,19 +18,19 @@ bool JoinMessage::Read(Stream& ms)
|
|||
{
|
||||
if(!Reply)
|
||||
{
|
||||
Version = ms.Read<byte>();
|
||||
Kind = ms.Read<ushort>();
|
||||
TranID = ms.Read<uint>();
|
||||
Version = ms.ReadByte();
|
||||
Kind = ms.ReadUInt16();
|
||||
TranID = ms.ReadUInt32();
|
||||
HardID = ms.ReadArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
Server = ms.Read<byte>();
|
||||
Channel = ms.Read<byte>();
|
||||
Speed = ms.Read<byte>();
|
||||
Address = ms.Read<byte>();
|
||||
Server = ms.ReadByte();
|
||||
Channel = ms.ReadByte();
|
||||
Speed = ms.ReadByte();
|
||||
Address = ms.ReadByte();
|
||||
Password= ms.ReadArray();
|
||||
TranID = ms.Read<uint>();
|
||||
TranID = ms.ReadUInt32();
|
||||
HardID = ms.ReadArray();
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ bool TinyMessage::Read(Stream& ms)
|
|||
if(Length > 0) ms.Read(Data, 0, Length);
|
||||
|
||||
// 读取真正的校验码
|
||||
Checksum = ms.Read<ushort>();
|
||||
Checksum = ms.ReadUInt16();
|
||||
|
||||
// 计算Crc之前,需要清零TTL和Retry
|
||||
byte fs = p[3];
|
||||
|
|
|
@ -33,15 +33,15 @@ HelloMessage::HelloMessage(HelloMessage& msg) : Ciphers(1), Key(0)
|
|||
// 从数据流中读取消息
|
||||
bool HelloMessage::Read(Stream& ms)
|
||||
{
|
||||
Version = ms.Read<ushort>();
|
||||
Version = ms.ReadUInt16();
|
||||
|
||||
Type = ms.ReadString();
|
||||
Name = ms.ReadString();
|
||||
|
||||
LocalTime = ms.Read<ulong>();
|
||||
LocalTime = ms.ReadUInt64();
|
||||
|
||||
EndPoint.Address = ms.ReadBytes(4);
|
||||
EndPoint.Port = ms.Read<ushort>();
|
||||
EndPoint.Port = ms.ReadUInt16();
|
||||
|
||||
if(!Reply)
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ bool HelloMessage::Read(Stream& ms)
|
|||
}
|
||||
else
|
||||
{
|
||||
Ciphers[0] = ms.Read<byte>();
|
||||
Ciphers[0] = ms.ReadByte();
|
||||
// 读取数组前,先设置为0,避免实际长度小于数组长度
|
||||
Key.SetLength(0);
|
||||
Key = ms.ReadArray();
|
||||
|
|
|
@ -16,7 +16,7 @@ bool LoginMessage::Read(Stream& ms)
|
|||
ms.ReadArray(Salt);
|
||||
|
||||
Local.Address = ms.ReadBytes(4);
|
||||
Local.Port = ms.Read<ushort>();
|
||||
Local.Port = ms.ReadUInt16();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ bool TokenClient::OnHello(TokenMessage& msg)
|
|||
Status = 0;
|
||||
Token = 0;
|
||||
Stream ms(msg.Data, msg.Length);
|
||||
debug_printf("握手失败,错误码=0x%02X ", ms.Read<byte>());
|
||||
debug_printf("握手失败,错误码=0x%02X ", ms.ReadByte());
|
||||
ms.ReadString().Show(true);
|
||||
}
|
||||
else
|
||||
|
@ -241,7 +241,7 @@ bool TokenClient::OnLogin(TokenMessage& msg)
|
|||
// 登录失败,清空令牌
|
||||
Token = 0;
|
||||
|
||||
byte result = ms.Read<byte>();
|
||||
byte result = ms.ReadByte();
|
||||
//if(result == 0xFF) Status = 0;
|
||||
// 任何错误,重新握手
|
||||
Status = 0;
|
||||
|
@ -256,10 +256,10 @@ bool TokenClient::OnLogin(TokenMessage& msg)
|
|||
|
||||
if(IsOldOrder)
|
||||
{
|
||||
byte stat=ms.Read<byte>();//旧指令,读走状态码
|
||||
byte stat=ms.ReadByte();//旧指令,读走状态码
|
||||
}
|
||||
// 得到令牌
|
||||
Token = ms.Read<int>();
|
||||
Token = ms.ReadUInt32();
|
||||
debug_printf("令牌:0x%08X ", Token);
|
||||
// 这里可能有通信密码
|
||||
if(ms.Remain() > 0)
|
||||
|
|
|
@ -26,11 +26,11 @@ bool TokenMessage::Read(Stream& ms)
|
|||
assert_ptr(this);
|
||||
if(ms.Remain() < MinSize) return false;
|
||||
|
||||
byte temp = ms.Read<byte>();
|
||||
byte temp = ms.ReadByte();
|
||||
Code = temp & 0x3f;
|
||||
Reply = temp >> 7;
|
||||
Error = (temp >> 6) & 0x01;
|
||||
Length = ms.Read<byte>();
|
||||
Length = ms.ReadByte();
|
||||
|
||||
// 占位符拷贝到实际数据
|
||||
/*Code = _Code;
|
||||
|
|
Loading…
Reference in New Issue