登录完成时会重新给密码

This commit is contained in:
WangQiang 2016-05-04 09:48:03 +00:00
parent ac8a84b9f2
commit 013655580c
7 changed files with 227 additions and 140 deletions

View File

@ -99,7 +99,7 @@ void Gateway::Stop()
Running = false;
}
// 数据接收中心
// 数据接收中心 TinyServer 上级
bool Gateway::OnLocal(const TinyMessage& msg)
{
TS("Gateway::OnLocal");
@ -132,6 +132,7 @@ bool Gateway::OnLocal(const TinyMessage& msg)
return true;
}
// 数据接收中心 TokenClient 上级
bool Gateway::OnRemote(const TokenMessage& msg)
{
TS("Gateway::OnRemote");
@ -139,16 +140,18 @@ bool Gateway::OnRemote(const TokenMessage& msg)
switch(msg.Code)
{
case 0x02:
// 登录以后自动发送设备列表和设备信息
if(msg.Reply && Client->Token != 0)
{
// 遍历发送所有设备信息
pDevMgmt->SendDevices(DeviceAtions::List, nullptr);
}
//// 登录以后自动发送设备列表和设备信息
//if(msg.Reply && Client->Token != 0)
//{
// // 遍历发送所有设备信息
// pDevMgmt->SendDevices(DeviceAtions::List, nullptr);
//}
break;
case 0x20:
return OnMode(msg);
//return OnMode(msg);
break;
case 0x21:
return pDevMgmt->DeviceProcess(msg);
}

View File

@ -134,3 +134,43 @@ String& HelloMessage::ToStr(String& str) const
return str;
}
#endif
TokenPingMessage::TokenPingMessage()
{
thisTime = Time.Now().TotalMicroseconds();
}
TokenPingMessage::TokenPingMessage(const TokenPingMessage& msg)
{
thisTime = msg.thisTime;
}
// 从数据流中读取消息
bool TokenPingMessage::Read(Stream& ms)
{
BinaryPair bp(ms);
bp.Get("Time", thisTime);
return true;
}
// 把消息写入数据流中
void TokenPingMessage::Write(Stream& ms) const
{
BinaryPair bp(ms);
bp.Set("Time", thisTime);
}
#if DEBUG
// 显示消息内容
String& TokenPingMessage::ToStr(String& str) const
{
str += "Ping";
if (Reply) str += '#';
DateTime dt;
dt.ParseUs(thisTime);
str += dt;
return str;
}
#endif

View File

@ -43,4 +43,23 @@ public:
#endif
};
class TokenPingMessage : public MessageBase
{
public:
UInt64 thisTime; // 时间ms
TokenPingMessage();
TokenPingMessage(const TokenPingMessage& msg);
// 从数据流中读取消息
virtual bool Read(Stream& ms);
// 把消息写入数据流中
virtual void Write(Stream& ms) const;
// 显示消息内容
#if DEBUG
virtual String& ToStr(String& str) const;
#endif
};
#endif

View File

@ -3,7 +3,7 @@
#include "Message\BinaryPair.h"
// 初始化消息各字段为0
LoginMessage::LoginMessage()
LoginMessage::LoginMessage() : Key(0)
{
}
@ -21,6 +21,7 @@ bool LoginMessage::Read(Stream& ms)
{
bp.Get("Token", Token);
bp.Get("Password", Pass);
bp.Get("Key",Key);
}
return false;
}

View File

@ -12,7 +12,8 @@ public:
String Pass; // 登录密码
ByteArray Salt; // 加盐
uint Token; //令牌
uint Token; // 令牌
ByteArray Key; // 登录时会发通讯密码
// 初始化消息各字段为0
LoginMessage();

View File

@ -232,7 +232,7 @@ bool TokenClient::OnHello(TokenMessage& msg, Controller* ctrl)
debug_printf("握手失败,错误码=0x%02X ", ext.ErrCode);
ext.ErrMsg.Show(true);
// 未握手错误,马上重新握手
if(ext.ErrCode == 0x7F) Sys.SetTask(_task, true, 0);
}
@ -435,22 +435,37 @@ bool TokenClient::OnLogin(TokenMessage& msg, Controller* ctrl)
Status = 2;
debug_printf("登录成功! ");
// 得到令牌
Token = ms.ReadUInt32();
debug_printf("令牌0x%08X ", Token);
// 这里可能有通信密码
if(ms.Remain() > 0)
{
auto bs = ms.ReadArray();
if(bs.Length() > 0)
{
auto ctrl2 = dynamic_cast<TokenController*>(ctrl);
if(ctrl2) ctrl2->Key.Copy(0, bs, 0, -1);
debug_printf("通信密码:");
bs.Show();
}
LoginMessage logMsg;
logMsg.ReadMessage(msg);
Token = logMsg.Token;
logMsg.Show(true);
debug_printf("令牌0x%08X ", Token);
if (logMsg.Key.Length())
{
auto ctrl2 = dynamic_cast<TokenController*>(ctrl);
if (ctrl2) ctrl2->Key = logMsg.Key;
debug_printf("通信密码:");
logMsg.Key.Show();
}
//// 得到令牌
//Token = ms.ReadUInt32();
//debug_printf("令牌0x%08X ", Token);
//// 这里可能有通信密码
//if(ms.Remain() > 0)
//{
// auto bs = ms.ReadArray();
// if(bs.Length() > 0)
// {
// auto ctrl2 = dynamic_cast<TokenController*>(ctrl);
// if(ctrl2) ctrl2->Key.Copy(0, bs, 0, -1);
// debug_printf("通信密码:");
// bs.Show();
// }
//}
debug_printf("\r\n");
}
@ -467,19 +482,18 @@ void TokenClient::Ping()
// 30秒无法联系服务端可能已经掉线重启Hello任务
debug_printf("30秒无法联系服务端可能已经掉线重新开始握手\r\n");
auto ctrl2 = dynamic_cast<TokenController*>(Control);
if (ctrl2) ctrl2->Key.SetLength(0);
Status = 0;
return;
}
TokenPingMessage pinMsg;
TokenMessage msg(3);
UInt64 time = Sys.Ms();
Buffer bs(&time, 8);
auto ms = msg.ToStream();
ms.WriteArray(bs);
msg.Length = ms.Position();
pinMsg.WriteMessage(msg);
Send(msg);
}
@ -488,14 +502,23 @@ bool TokenClient::OnPing(TokenMessage& msg, Controller* ctrl)
{
TS("TokenClient::OnPing");
// 忽略
if(!msg.Reply) return Reply(msg, ctrl);
if (!msg.Reply) return false;
auto ms = msg.ToStream();
TokenPingMessage pinMsg;
pinMsg.ReadMessage(msg);
UInt64 start = pinMsg.thisTime;
UInt64 now = Sys.Ms();
auto bs = ms.ReadArray();
UInt64 start = bs.ToUInt64();
//// 忽略
//if(!msg.Reply) return Reply(msg, ctrl);
//auto ms = msg.ToStream();
//BinaryPair bp(ms);
//ByteArray bs;
//bp.Get("Time", bs);
//UInt64 start = bs.ToUInt64();
UInt64 now = Sys.Ms();
int cost = (int)(now - start);
if(cost < 0) cost = -cost;
if(cost > 1000) ((TTime&)Time).SetTime(start / 1000);

View File

@ -45,7 +45,7 @@ private:
};
// 全局的令牌统计指针
static TokenStat* Stat = nullptr;
static TokenStat* Stat = nullptr;
#if DEBUG
static void StatTask(void* param);
@ -55,11 +55,11 @@ static void StatTask(void* param);
TokenController::TokenController() : Controller(), Key(0)
{
Token = 0;
Token = 0;
MinSize = TokenMessage::MinSize;
Server = nullptr;
Server = nullptr;
// 默认屏蔽心跳日志和确认日志
Buffer(NoLogCodes, sizeof(NoLogCodes)).Clear();
@ -75,21 +75,21 @@ TokenController::~TokenController()
void TokenController::Open()
{
if(Opened) return;
if (Opened) return;
assert(Port, "还没有传输口呢");
debug_printf("TokenNet::Inited 使用传输接口 ");
#if DEBUG
auto obj = dynamic_cast<Object*>(Port);
if(obj) obj->Show(true);
auto obj = dynamic_cast<Object*>(Port);
if (obj) obj->Show(true);
//Port->Show(true);
#endif
auto sock = dynamic_cast<ISocket*>(Port);
if(sock) Server = &sock->Remote;
auto sock = dynamic_cast<ISocket*>(Port);
if (sock) Server = &sock->Remote;
if(!Stat)
if (!Stat)
{
Stat = new TokenStat();
#if DEBUG
@ -126,21 +126,21 @@ bool TokenController::Valid(const Message& msg)
TS("TokenController::Valid");
// 代码为0是非法的
if(!msg.Code) return false;
if (!msg.Code) return false;
// 握手和登录指令可直接通过
if(msg.Code <= 0x02) return true;
if (msg.Code <= 0x02) return true;
if(Token != 0) return true;
if (Token != 0) return true;
// 合法来源验证,暂时验证云平台,其它连接将来验证
auto svr = (IPEndPoint*)Server;
auto rmt = (IPEndPoint*)msg.State;
auto svr = (IPEndPoint*)Server;
auto rmt = (IPEndPoint*)msg.State;
if(!rmt || svr && *svr != *rmt)
if (!rmt || svr && *svr != *rmt)
{
debug_printf("Token::Valid 非法来源 ");
if(rmt) rmt->Show();
if (rmt) rmt->Show();
debug_printf("\r\n");
return false;
}
@ -161,21 +161,21 @@ static bool Encrypt(Buffer& data, const Buffer& pass)
if (pass.Length() == 0) return true;
// 握手不加密
byte code = data[0] & 0x0F;
if(code == 0x01) return true;
byte code = data[0] & 0x0F;
if (code == 0x01) return true;
Stream ms(data);
ms.Seek(2);
auto len = ms.ReadEncodeInt();
//auto bs = ms.ReadArray(len);
ByteArray bs(ms.GetBuffer()+ms.Position(), len);
ByteArray bs(ms.GetBuffer() + ms.Position(), len);
ms.Seek(len);
//todo 还需要两个字节空余后面的SetLength不一定生效
// 计算明文校验码,写在最后面
auto crc = Crc::Hash16(bs);
auto crc = Crc::Hash16(bs);
RC4::Encrypt(bs, pass);
ms.Write(crc);
@ -184,8 +184,8 @@ static bool Encrypt(Buffer& data, const Buffer& pass)
// Decrypt(Buffer(msg.Data,len),Key) 只处理data部分
static bool Decrypt(Buffer& data, const Buffer& pass)
{
if(data.Length() <= 3) return false;
if(pass.Length() == 0) return true;
if (data.Length() <= 3) return false;
if (pass.Length() == 0) return true;
auto msgDataLen = data.Length() - 2;
Stream ms(data);
@ -193,11 +193,11 @@ static bool Decrypt(Buffer& data, const Buffer& pass)
auto crc = ms.ReadUInt16(); // 读取数据包中crc
data.SetLength(msgDataLen);
ByteArray bs(data.GetBuffer(),data.Length());
ByteArray bs(data.GetBuffer(), data.Length());
RC4::Encrypt(bs, pass); // 解密
auto crc2 = Crc::Hash16(bs); // 明文的CRC值
if(crc != crc2) return false;
auto crc2 = Crc::Hash16(bs); // 明文的CRC值
if (crc != crc2) return false;
return true;
}
@ -207,12 +207,12 @@ bool TokenController::OnReceive(Message& msg)
{
TS("TokenController::OnReceive");
if(msg.Reply)
if (msg.Reply)
{
bool rs = EndSendStat(msg.Code, true);
// 如果匹配了发送队列,那么这里不再作为收到响应
if(!rs) Stat->RecvReplyAsync++;
if (!rs) Stat->RecvReplyAsync++;
}
else
{
@ -224,14 +224,14 @@ bool TokenController::OnReceive(Message& msg)
// 加解密。握手不加密,登录响应不加密
//Encrypt(msg, Key);
Buffer bs(msg.Data, msg.Length + 2);
if(!Decrypt(bs, Key)) return false;
if (!Decrypt(bs, Key)) return false;
ShowMessage("Recv", msg);
return Controller::OnReceive(msg);
}
static byte _Sequence = 0;
static byte _Sequence = 0;
// 发送消息,传输口参数为空时向所有传输口发送消息
bool TokenController::Send(Message& msg)
{
@ -240,11 +240,11 @@ bool TokenController::Send(Message& msg)
//if(Token == 0&&!( msg.Code <= 0x2||msg.Code == 0x07)) return false;
//static byte _Sequence = 0;
auto& tmsg = (TokenMessage&)msg;
auto& tmsg = (TokenMessage&)msg;
// 附上序列号。响应消息保持序列号不变
if(!msg.Reply && tmsg.Seq == 0) tmsg.Seq = ++_Sequence;
if (!msg.Reply && tmsg.Seq == 0) tmsg.Seq = ++_Sequence;
if(msg.Reply)
if (msg.Reply)
ShowMessage("Reply", msg);
else
ShowMessage("Send", msg);
@ -253,7 +253,7 @@ bool TokenController::Send(Message& msg)
//Encrypt(msg, Key);
// 加入统计
if(!msg.Reply) StartSendStat(msg.Code);
if (!msg.Reply) StartSendStat(msg.Code);
return Controller::Send(msg);
}
@ -265,7 +265,7 @@ bool TokenController::SendInternal(const Buffer& bs, const void* state)
arr = bs;
arr.SetLength(len);
if(!Encrypt(arr, Key)) return false;
if (!Encrypt(arr, Key)) return false;
return Controller::SendInternal(arr, state);
}
@ -275,19 +275,19 @@ void TokenController::ShowMessage(const char* action, const Message& msg)
#if MSG_DEBUG
TS("TokenController::ShowMessage");
for(int i=0; i<ArrayLength(NoLogCodes); i++)
for (int i = 0; i < ArrayLength(NoLogCodes); i++)
{
if(msg.Code == NoLogCodes[i]) return;
if(NoLogCodes[i] == 0) break;
if (msg.Code == NoLogCodes[i]) return;
if (NoLogCodes[i] == 0) break;
}
debug_printf("Token::%s ", action);
if(msg.State)
if (msg.State)
{
auto svr = (IPEndPoint*)Server;
auto rmt = (IPEndPoint*)msg.State;
if(!svr || *svr != *rmt)
auto svr = (IPEndPoint*)Server;
auto rmt = (IPEndPoint*)msg.State;
if (!svr || *svr != *rmt)
{
rmt->Show();
debug_printf(" ");
@ -297,10 +297,10 @@ void TokenController::ShowMessage(const char* action, const Message& msg)
msg.Show();
// 如果是错误,显示错误信息
if(msg.Error)
if (msg.Error)
{
debug_printf("Error=0x%02X ", msg.Data[0]);
if(msg.Data[0] == 0x01 && msg.Length - 1 < 0x40)
if (msg.Data[0] == 0x01 && msg.Length - 1 < 0x40)
{
Stream ms(msg.Data + 1, msg.Length - 1);
ms.ReadString().Show(false);
@ -314,7 +314,7 @@ bool TokenController::StartSendStat(byte code)
{
TS("TokenController::StartSendStat");
auto st = Stat;
auto st = Stat;
// 仅统计请求信息,不统计响应信息
if ((code & 0x80) != 0)
@ -330,12 +330,12 @@ bool TokenController::StartSendStat(byte code)
else if (code2 == 0x16 || code2 == 0x06)
st->Write++;
for(int i=0; i<ArrayLength(_Queue); i++)
for (int i = 0; i < ArrayLength(_Queue); i++)
{
if(_Queue[i].Code == 0)
if (_Queue[i].Code == 0)
{
_Queue[i].Code = code;
_Queue[i].Time = Sys.Ms();
_Queue[i].Code = code;
_Queue[i].Time = Sys.Ms();
return true;
}
}
@ -347,21 +347,21 @@ bool TokenController::EndSendStat(byte code, bool success)
{
TS("TokenController::EndSendStat");
auto st = Stat;
auto st = Stat;
byte code2 = code & 0x3F;
for(int i=0; i<ArrayLength(_Queue); i++)
for (int i = 0; i < ArrayLength(_Queue); i++)
{
if(_Queue[i].Code == code2)
if (_Queue[i].Code == code2)
{
bool rs = false;
if(success)
if (success)
{
int cost = (int)(Sys.Ms() - _Queue[i].Time);
// 莫名其妙,有时候竟然是负数
if(cost < 0) cost = -cost;
if(cost < 1000)
if (cost < 0) cost = -cost;
if (cost < 1000)
{
st->RecvReply++;
st->Time += cost;
@ -370,7 +370,7 @@ bool TokenController::EndSendStat(byte code, bool success)
}
}
_Queue[i].Code = 0;
_Queue[i].Code = 0;
return rs;
}
@ -396,30 +396,30 @@ TokenStat::TokenStat()
TokenStat::~TokenStat()
{
if (_Last == nullptr) delete _Last;
if (_Total == nullptr) delete _Total;
if (_Last == nullptr) delete _Last;
if (_Total == nullptr) delete _Total;
}
String CaclPercent(int d1, int d2)
{
String str;
if(d2 == 0) return str + "0";
if (d2 == 0) return str + "0";
// 分开处理整数部分和小数部分
d1 *= 100;
int d = d1 / d2;
d1 *= 100;
int d = d1 / d2;
//d1 %= d2;
// %会产生乘减指令MLS再算一次除法
d1 -= d * d2;
d1 *= 100;
int f = d1 / d2;
d1 -= d * d2;
d1 *= 100;
int f = d1 / d2;
str += d;
if(f > 0)
str += d;
if (f > 0)
{
str += ".";
if(f < 10) str += "0";
str += f;
str += ".";
if (f < 10) str += "0";
str += f;
}
return str;
@ -429,7 +429,7 @@ String TokenStat::Percent() const
{
int send = SendRequest;
int sucs = RecvReply;
if(_Last)
if (_Last)
{
send += _Last->SendRequest;
sucs += _Last->RecvReply;
@ -442,12 +442,12 @@ int TokenStat::Speed() const
{
int time = Time;
int sucs = RecvReply;
if(_Last)
if (_Last)
{
time += _Last->Time;
sucs += _Last->RecvReply;
}
if(sucs == 0) return 0;
if (sucs == 0) return 0;
return time / sucs;
}
@ -456,7 +456,7 @@ String TokenStat::PercentReply() const
{
int req = RecvRequest;
int rep = SendReply;
if(_Last)
if (_Last)
{
req += _Last->RecvRequest;
rep += _Last->SendReply;
@ -470,40 +470,40 @@ void TokenStat::Clear()
if (_Last == nullptr) _Last = new TokenStat();
if (_Total == nullptr) _Total = new TokenStat();
_Last->SendRequest = SendRequest;
_Last->RecvReply = RecvReply;
_Last->SendReply = SendReply;
_Last->SendRequest = SendRequest;
_Last->RecvReply = RecvReply;
_Last->SendReply = SendReply;
_Last->Time = Time;
_Last->RecvRequest = RecvRequest;
_Last->RecvReplyAsync = RecvReplyAsync;
_Last->Read = Read;
_Last->ReadReply = ReadReply;
_Last->Write = Write;
_Last->WriteReply = WriteReply;
_Last->RecvRequest = RecvRequest;
_Last->RecvReplyAsync = RecvReplyAsync;
_Last->Read = Read;
_Last->ReadReply = ReadReply;
_Last->Write = Write;
_Last->WriteReply = WriteReply;
_Total->SendRequest += SendRequest;
_Total->RecvReply += RecvReply;
_Total->SendReply += SendReply;
_Total->SendRequest += SendRequest;
_Total->RecvReply += RecvReply;
_Total->SendReply += SendReply;
_Total->Time += Time;
_Total->RecvRequest += RecvRequest;
_Total->RecvReplyAsync += RecvReplyAsync;
_Total->Read += Read;
_Total->ReadReply += ReadReply;
_Total->Write += Write;
_Total->WriteReply += WriteReply;
_Total->RecvRequest += RecvRequest;
_Total->RecvReplyAsync += RecvReplyAsync;
_Total->Read += Read;
_Total->ReadReply += ReadReply;
_Total->Write += Write;
_Total->WriteReply += WriteReply;
SendRequest = 0;
RecvReply = 0;
Time = 0;
SendRequest = 0;
RecvReply = 0;
Time = 0;
SendReply = 0;
RecvRequest = 0;
RecvReplyAsync = 0;
SendReply = 0;
RecvRequest = 0;
RecvReplyAsync = 0;
Read = 0;
ReadReply = 0;
Write = 0;
WriteReply = 0;
Read = 0;
ReadReply = 0;
Write = 0;
WriteReply = 0;
}
String& TokenStat::ToStr(String& str) const
@ -515,10 +515,10 @@ String& TokenStat::ToStr(String& str) const
Percent().Show(true);*/
str = str + "发:" + Percent() + "% " + RecvReply + "/" + SendRequest + " " + Speed() + "ms";
str = str + " 收:" + PercentReply() + "% " + SendReply + "/" + RecvRequest;
if(RecvReplyAsync > 0) str = str + " 异步 " + RecvReplyAsync;
if (RecvReplyAsync > 0) str = str + " 异步 " + RecvReplyAsync;
if (Read > 0) str = str + " 读:" + (ReadReply * 100 / Read) + " " + ReadReply + "/" + Read;
if (Write > 0) str = str + " 写:" + (WriteReply * 100 / Write) + " " + WriteReply + "/" + Write;
if(_Total)
if (_Total)
{
str += "";
_Total->ToStr(str);