握手重定向消息直接在握手消息内部解析

This commit is contained in:
nnhy 2016-01-16 02:53:23 +00:00
parent 8b8a9a6cc9
commit 152f91f8b6
6 changed files with 92 additions and 56 deletions

View File

@ -4,13 +4,21 @@
MessageBase::MessageBase()
{
Reply = false;
Error = false;
}
MessageBase::MessageBase(const MessageBase& msg)
{
Reply = msg.Reply;
Error = msg.Error;
}
bool MessageBase::ReadMessage(const Message& msg)
{
TS("MessageBase::ReadMessage");
Reply = msg.Reply;
Reply = msg.Reply;
Error = msg.Error;
Stream ms(msg.Data, msg.Length);
return Read(ms);

View File

@ -9,10 +9,12 @@
class MessageBase : public Object
{
public:
bool Reply; // 是否响应
bool Reply; // 是否响应
bool Error; // 是否错误
// 初始化消息各字段为0
MessageBase();
MessageBase(const MessageBase& msg);
// 从数据流中读取消息
virtual bool Read(Stream& ms) = 0;

View File

@ -1,8 +1,9 @@
#include "Time.h"
#include "HelloMessage.h"
// 请求2版本 + S类型 + S名称 + 8本地时间 + 本地IP端口 + S支持加密算法列表
// 响应2版本 + S类型 + S名称 + 8对方时间 + 对方IP端口 + S加密算法 + N密钥
// 请求2版本 + S类型 + S名称 + 8本地时间 + 6本地IP端口 + S支持加密算法列表
// 响应2版本 + S类型 + S名称 + 8本地时间 + 6对方IP端口 + 1加密算法 + N密钥
// 错误0xFE + 1协议 + S服务器 + 2端口
// 初始化消息各字段为0
HelloMessage::HelloMessage() : Ciphers(1), Key(0)
@ -15,10 +16,12 @@ HelloMessage::HelloMessage() : Ciphers(1), Key(0)
Name = Sys.Company;
LocalTime = Time.Now().TotalMicroseconds();
Ciphers[0] = 1;
Protocol = 2;
Port = 0;
}
HelloMessage::HelloMessage(HelloMessage& msg) : Ciphers(1), Key(0)
HelloMessage::HelloMessage(const HelloMessage& msg) : MessageBase(msg), Ciphers(1), Key(0)
{
Version = msg.Version;
Type = msg.Type;
@ -27,20 +30,36 @@ HelloMessage::HelloMessage(HelloMessage& msg) : Ciphers(1), Key(0)
EndPoint = msg.EndPoint;
Ciphers = msg.Ciphers;
Key = msg.Key;
Reply = msg.Reply;
Protocol = msg.Protocol;
Port = msg.Port;
Server = msg.Server;
}
// 从数据流中读取消息
bool HelloMessage::Read(Stream& ms)
{
{
if(Reply && Error)
{
byte err = ms.ReadByte();
if(err == 0xFE || err == 0xFD)
{
Protocol = ms.ReadByte();
Server = ms.ReadArray();
Port = ms.ReadUInt16();
}
else
{
debug_printf("无法识别错误码 0x%02X \r\n", err);
return false;
}
}
Version = ms.ReadUInt16();
Type = ms.ReadString();
Name = ms.ReadString();
LocalTime = ms.ReadUInt64();
//EndPoint.Address = ms.ReadBytes(4);
//EndPoint.Port = ms.ReadUInt16();
EndPoint = ms.ReadArray(6);
if(!Reply)
@ -62,17 +81,9 @@ bool HelloMessage::Read(Stream& ms)
void HelloMessage::Write(Stream& ms) const
{
ms.Write(Version);
ms.WriteArray(Type);
if(Name.Length() != 0)
ms.WriteArray(Name);
else
ms.WriteArray(String(Sys.Company));
ms.WriteArray(Name);
ms.Write(LocalTime);
//ms.Write(EndPoint.Address.ToArray());
//ms.Write((ushort)EndPoint.Port);
ms.Write(EndPoint.ToArray());
if(!Reply)
@ -92,6 +103,20 @@ String& HelloMessage::ToStr(String& str) const
{
str += "握手";
if(Reply) str += "#";
if(Reply && Error)
{
if(Protocol == 1)
str = str + " TCP ";
else if(Protocol == 2)
str = str + " UDP ";
str += Server;
str = str + " " + Port;
return str;
}
str.Append(" Ver=").Append(Version, 16, 4);
str = str + " " + Type + " " + Name + " ";

View File

@ -5,8 +5,9 @@
#include "Net\Net.h"
// 握手消息
// 请求2版本 + S类型 + S名称 + 8本地时间 + 本地IP端口 + S支持加密算法列表
// 响应2版本 + S类型 + S名称 + 8对方时间 + 对方IP端口 + 1加密算法 + N密钥
// 请求2版本 + S类型 + S名称 + 8本地时间 + 6本地IP端口 + S支持加密算法列表
// 响应2版本 + S类型 + S名称 + 8本地时间 + 6对方IP端口 + 1加密算法 + N密钥
// 错误0xFE + 1协议 + S服务器 + 2端口
class HelloMessage : public MessageBase
{
public:
@ -21,16 +22,17 @@ public:
byte ErrCode; // 错误码
byte Protocol; // 协议TCP=1/UDP=2
ushort Port; // 本地端口
byte Protocol; // 协议TCP=1/UDP=2
ushort Port; // 本地端口
String Server; // 服务器地址。可能是域名或IP
uint ServerIP; // 服务器IP地址。服务器域名解析成功后覆盖
ushort ServerPort; // 服务器端口
char Server[32]; // 服务器域名。出厂为空,从厂商服务器覆盖,恢复出厂设置时清空
//uint ServerIP; // 服务器IP地址。服务器域名解析成功后覆盖
//ushort ServerPort; // 服务器端口
//char Server[32]; // 服务器域名。出厂为空,从厂商服务器覆盖,恢复出厂设置时清空
// 初始化消息各字段为0
HelloMessage();
HelloMessage(HelloMessage& msg);
HelloMessage(const HelloMessage& msg);
// 从数据流中读取消息
virtual bool Read(Stream& ms);

View File

@ -149,8 +149,9 @@ void LoopTask(void* param)
}
// 发送发现消息,告诉大家我在这
// 请求2版本 + S类型 + S名称 + 8本地时间 + 本地IP端口 + N支持加密算法列表
// 响应2版本 + S类型 + S名称 + 8对方时间 + 对方IP端口 + 1加密算法 + N密钥
// 请求2版本 + S类型 + S名称 + 8本地时间 + 6本地IP端口 + S支持加密算法列表
// 响应2版本 + S类型 + S名称 + 8本地时间 + 6对方IP端口 + 1加密算法 + N密钥
// 错误0xFE + 1协议 + S服务器 + 2端口
void TokenClient::SayHello(bool broadcast, int port)
{
TokenMessage msg(0x01);
@ -186,12 +187,19 @@ void TokenClient::SayHello(bool broadcast, int port)
// 握手响应
bool TokenClient::OnHello(TokenMessage& msg, Controller* ctrl)
{
// 解析数据
HelloMessage ext;
ext.Reply = msg.Reply;
ext.ReadMessage(msg);
ext.Show(true);
// 如果收到响应,并且来自来源服务器
if(msg.Reply)
{
if(msg.Error)
{
if(HelloRedirect(msg)) return false;
if(OnRedirect(ext)) return false;
Stream ms = msg.ToStream();
byte err = ms.ReadByte();
@ -207,13 +215,6 @@ bool TokenClient::OnHello(TokenMessage& msg, Controller* ctrl)
}
else
{
// 解析数据
HelloMessage ext;
ext.Reply = msg.Reply;
ext.ReadMessage(msg);
ext.Show(true);
// 通讯密码
if(ext.Key.Length() > 0)
{
@ -269,27 +270,24 @@ bool TokenClient::OnHello(TokenMessage& msg, Controller* ctrl)
return true;
}
bool TokenClient::HelloRedirect(TokenMessage& msg)
bool TokenClient::OnRedirect(const HelloMessage& msg) const
{
// 解析数据
Stream ms(msg.Data, msg.Length);
if(ms.ReadByte() != 0xFE) return false;
if(msg.ErrCode != 0xFE && msg.ErrCode != 0xFD) return false;
auto cfg = TokenConfig::Current;
cfg->Protocol = ms.ReadByte();
cfg->Protocol = msg.Protocol;
uint len = ms.ReadByte();
if(len > ArrayLength(cfg-> Server)) len = ArrayLength(cfg-> Server);
for(int i=0;i!=len;i++)
uint len = ArrayLength(cfg->Server);
if(msg.Server.Length() > len)
{
cfg-> Server[i]=ms.ReadByte();
}
debug_printf("服务器地址超长 Max=%d Server=%s \r\n", len, msg.Server.GetBuffer());
return false;
}
msg.Server.CopyTo(cfg->Server, 0, 0);
cfg->Port = msg.Port;
cfg->ServerPort = ms.ReadUInt16();
debug_printf("cfg->ServerPort:%d\r\n",cfg->ServerPort);
strcpy(cfg->Vendor, "s1.peacemoon.cn");
// 0xFD永久改变厂商地址
if(msg.ErrCode != 0xFD) msg.Server.CopyTo(cfg->Vendor, 0, 0);
cfg->Save();
cfg->Show();
@ -298,6 +296,7 @@ bool TokenClient::HelloRedirect(TokenMessage& msg)
return true;
}
//注册
void TokenClient::Register()
{

View File

@ -53,15 +53,15 @@ public:
HelloMessage Hello;
void SayHello(bool broadcast = false, int port = 0);
bool OnHello(TokenMessage& msg, Controller* ctrl);
//注册
// 跳转
bool OnRedirect(const HelloMessage& msg) const;
// 注册
void Register();
void OnRegister(TokenMessage& msg, Controller* ctrl);
// 登录
void Login();
void Login(TokenMessage& msg,Controller* ctrl);
bool OnLogin(TokenMessage& msg, Controller* ctrl);
//设置网络配置
bool HelloRedirect(TokenMessage& msg);
// Ping指令用于保持与对方的活动状态
void Ping();