Browse Source

添加TCP通信工具类(TcppServer,TcppClient)并添加测试程序

yuzhengyang 7 years ago
parent
commit
57521b6ca3
40 changed files with 2244 additions and 568 deletions
  1. 0 59
      Azylee.Utils/Azylee.Core.Plus/Azylee.Core.Plus.csproj
  2. 0 326
      Azylee.Utils/Azylee.Core.Plus/DataUtils/JsonUtils/ConvertJson.cs
  3. 0 48
      Azylee.Utils/Azylee.Core.Plus/DataUtils/JsonUtils/JsonTool.cs
  4. 0 4
      Azylee.Utils/Azylee.Core.Plus/packages.config
  5. 20 51
      Azylee.Utils/Azylee.Core/AppUtils/AppLaunchTool.cs
  6. 1 1
      Azylee.Utils/Azylee.Core/WindowsUtils/BrowserUtils/BrowserSelector.cs
  7. 16 0
      Azylee.Utils/Azylee.Core/WindowsUtils/ConsoleUtils/Cons.cs
  8. 1 0
      Azylee.Utils/Azylee.Jsons/Azylee.Jsons.csproj
  9. 56 1
      Azylee.Utils/Azylee.Jsons/Json.cs
  10. 0 4
      Azylee.Utils/Azylee.Update/Azylee.Update.csproj
  11. 14 14
      Azylee.Utils/Azylee.Utils.sln
  12. 8 0
      Azylee.Utils/Azylee.YeahWeb/Azylee.YeahWeb.csproj
  13. 14 0
      Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpClientDictionary.cs
  14. 42 0
      Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpDataConverter.cs
  15. 67 0
      Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpDataModel.cs
  16. 30 0
      Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpDelegate.cs
  17. 95 0
      Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpStreamHelper.cs
  18. 153 0
      Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcppClient.cs
  19. 231 0
      Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcppServer.cs
  20. 0 49
      Azylee.Utils/Tests/Test.ProcessTool/Program.cs
  21. 201 0
      Azylee.Utils/Tests/Test.TcpClientApp/MainForm.Designer.cs
  22. 93 0
      Azylee.Utils/Tests/Test.TcpClientApp/MainForm.cs
  23. 120 0
      Azylee.Utils/Tests/Test.TcpClientApp/MainForm.resx
  24. 36 0
      Azylee.Utils/Tests/Test.TcpClientApp/Program.cs
  25. 3 3
      Azylee.Utils/Tests/Test.ProcessTool/Properties/AssemblyInfo.cs
  26. 71 0
      Azylee.Utils/Tests/Test.TcpClientApp/Properties/Resources.Designer.cs
  27. 117 0
      Azylee.Utils/Tests/Test.TcpClientApp/Properties/Resources.resx
  28. 30 0
      Azylee.Utils/Tests/Test.TcpClientApp/Properties/Settings.Designer.cs
  29. 7 0
      Azylee.Utils/Tests/Test.TcpClientApp/Properties/Settings.settings
  30. 42 4
      Azylee.Utils/Tests/Test.ProcessTool/Test.ProcessTool.csproj
  31. 210 0
      Azylee.Utils/Tests/Test.TcpServerApp/MainForm.Designer.cs
  32. 104 0
      Azylee.Utils/Tests/Test.TcpServerApp/MainForm.cs
  33. 120 0
      Azylee.Utils/Tests/Test.TcpServerApp/MainForm.resx
  34. 22 0
      Azylee.Utils/Tests/Test.TcpServerApp/Program.cs
  35. 4 4
      Azylee.Utils/Azylee.Core.Plus/Properties/AssemblyInfo.cs
  36. 71 0
      Azylee.Utils/Tests/Test.TcpServerApp/Properties/Resources.Designer.cs
  37. 117 0
      Azylee.Utils/Tests/Test.TcpServerApp/Properties/Resources.resx
  38. 30 0
      Azylee.Utils/Tests/Test.TcpServerApp/Properties/Settings.Designer.cs
  39. 7 0
      Azylee.Utils/Tests/Test.TcpServerApp/Properties/Settings.settings
  40. 91 0
      Azylee.Utils/Tests/Test.TcpServerApp/Test.TcpServerApp.csproj

+ 0 - 59
Azylee.Utils/Azylee.Core.Plus/Azylee.Core.Plus.csproj

@@ -1,59 +0,0 @@
-<?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>{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Azylee.Core.Plus</RootNamespace>
-    <AssemblyName>Azylee.Core.Plus</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <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' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net40\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <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.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="DataUtils\JsonUtils\ConvertJson.cs" />
-    <Compile Include="DataUtils\JsonUtils\JsonTool.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Azylee.Core\Azylee.Core.csproj">
-      <Project>{88dc61fa-95f0-41b7-9d7d-ab0f3cbd169c}</Project>
-      <Name>Azylee.Core</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>

+ 0 - 326
Azylee.Utils/Azylee.Core.Plus/DataUtils/JsonUtils/ConvertJson.cs

@@ -1,326 +0,0 @@
-//############################################################
-//      https://github.com/yuzhengyang
-//      author:yuzhengyang
-//############################################################
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Data;
-using System.Reflection;
-using System.Collections;
-using System.Data.Common;
-
-namespace Azylee.Core.Plus.DataUtils.JsonUtils
-{
-    //JSON转换类
-    public class ConvertJson
-    {
-        #region 私有方法
-        /// <summary>
-        /// 过滤特殊字符
-        /// </summary>
-        private static string String2Json(String s)
-        {
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < s.Length; i++)
-            {
-                char c = s.ToCharArray()[i];
-                switch (c)
-                {
-                    case '\"':
-                        sb.Append("\\\""); break;
-                    case '\\':
-                        sb.Append("\\\\"); break;
-                    case '/':
-                        sb.Append("\\/"); break;
-                    case '\b':
-                        sb.Append("\\b"); break;
-                    case '\f':
-                        sb.Append("\\f"); break;
-                    case '\n':
-                        sb.Append("\\n"); break;
-                    case '\r':
-                        sb.Append("\\r"); break;
-                    case '\t':
-                        sb.Append("\\t"); break;
-                    default:
-                        sb.Append(c); break;
-                }
-            }
-            return sb.ToString();
-        }
-
-        /// <summary>
-        /// 格式化字符型、日期型、布尔型
-        /// </summary>
-        private static string StringFormat(string str, Type type)
-        {
-            if (type == typeof(string))
-            {
-                str = String2Json(str);
-                str = "\"" + str + "\"";
-            }
-            else if (type == typeof(DateTime))
-            {
-                str = "\"" + str + "\"";
-            }
-            else if (type == typeof(bool))
-            {
-                str = str.ToLower();
-            }
-            else if (type != typeof(string) && string.IsNullOrEmpty(str))
-            {
-                str = "\"" + str + "\"";
-            }
-            return str;
-        }
-        #endregion
-
-        #region List转换成Json
-        /// <summary>
-        /// List转换成Json
-        /// </summary>
-        public static string ListToJson<T>(IList<T> list)
-        {
-            object obj = list[0];
-            return ListToJson<T>(list, obj.GetType().Name);
-        }
-
-        /// <summary>
-        /// List转换成Json 
-        /// </summary>
-        public static string ListToJson<T>(IList<T> list, string jsonName)
-        {
-            StringBuilder Json = new StringBuilder();
-            if (string.IsNullOrEmpty(jsonName)) jsonName = list[0].GetType().Name;
-            Json.Append("{\"" + jsonName + "\":[");
-            if (list.Count > 0)
-            {
-                for (int i = 0; i < list.Count; i++)
-                {
-                    T obj = Activator.CreateInstance<T>();
-                    PropertyInfo[] pi = obj.GetType().GetProperties();
-                    Json.Append("{");
-                    for (int j = 0; j < pi.Length; j++)
-                    {
-                        Type type = pi[j].GetValue(list[i], null).GetType();
-                        Json.Append("\"" + pi[j].Name.ToString() + "\":" + StringFormat(pi[j].GetValue(list[i], null).ToString(), type));
-
-                        if (j < pi.Length - 1)
-                        {
-                            Json.Append(",");
-                        }
-                    }
-                    Json.Append("}");
-                    if (i < list.Count - 1)
-                    {
-                        Json.Append(",");
-                    }
-                }
-            }
-            Json.Append("]}");
-            return Json.ToString();
-        }
-        #endregion
-
-        #region 对象转换为Json
-        /// <summary> 
-        /// 对象转换为Json 
-        /// </summary> 
-        /// <param name="jsonObject">对象</param> 
-        /// <returns>Json字符串</returns> 
-        public static string ToJson(object jsonObject)
-        {
-            string jsonString = "{";
-            PropertyInfo[] propertyInfo = jsonObject.GetType().GetProperties();
-            for (int i = 0; i < propertyInfo.Length; i++)
-            {
-                object objectValue = propertyInfo[i].GetGetMethod().Invoke(jsonObject, null);
-                string value = string.Empty;
-                if (objectValue is DateTime || objectValue is Guid || objectValue is TimeSpan)
-                {
-                    value = "'" + objectValue.ToString() + "'";
-                }
-                else if (objectValue is string)
-                {
-                    value = "'" + ToJson(objectValue.ToString()) + "'";
-                }
-                else if (objectValue is IEnumerable)
-                {
-                    value = ToJson((IEnumerable)objectValue);
-                }
-                else
-                {
-                    value = ToJson(objectValue.ToString());
-                }
-                jsonString += "\"" + ToJson(propertyInfo[i].Name) + "\":" + value + ",";
-            }
-            jsonString.Remove(jsonString.Length - 1, jsonString.Length);
-            return jsonString + "}";
-        }
-        #endregion
-
-        #region 对象集合转换Json
-        /// <summary> 
-        /// 对象集合转换Json 
-        /// </summary> 
-        /// <param name="array">集合对象</param> 
-        /// <returns>Json字符串</returns> 
-        public static string ToJson(IEnumerable array)
-        {
-            string jsonString = "[";
-            foreach (object item in array)
-            {
-                jsonString += ToJson(item) + ",";
-            }
-            jsonString.Remove(jsonString.Length - 1, jsonString.Length);
-            return jsonString + "]";
-        }
-        #endregion
-
-        #region 普通集合转换Json
-        /// <summary> 
-        /// 普通集合转换Json 
-        /// </summary> 
-        /// <param name="array">集合对象</param> 
-        /// <returns>Json字符串</returns> 
-        public static string ToArrayString(IEnumerable array)
-        {
-            string jsonString = "[";
-            foreach (object item in array)
-            {
-                jsonString = ToJson(item.ToString()) + ",";
-            }
-            jsonString.Remove(jsonString.Length - 1, jsonString.Length);
-            return jsonString + "]";
-        }
-        #endregion
-
-        #region  DataSet转换为Json
-        /// <summary> 
-        /// DataSet转换为Json 
-        /// </summary> 
-        /// <param name="dataSet">DataSet对象</param> 
-        /// <returns>Json字符串</returns> 
-        public static string ToJson(DataSet dataSet)
-        {
-            string jsonString = "{";
-            foreach (DataTable table in dataSet.Tables)
-            {
-                jsonString += "\"" + table.TableName + "\":" + ToJson(table) + ",";
-            }
-            jsonString = jsonString.TrimEnd(',');
-            return jsonString + "}";
-        }
-        #endregion
-
-        #region Datatable转换为Json
-        /// <summary> 
-        /// Datatable转换为Json 
-        /// </summary> 
-        /// <param name="table">Datatable对象</param> 
-        /// <returns>Json字符串</returns> 
-        public static string ToJson(DataTable dt)
-        {
-            StringBuilder jsonString = new StringBuilder();
-            jsonString.Append("[");
-            DataRowCollection drc = dt.Rows;
-            for (int i = 0; i < drc.Count; i++)
-            {
-                jsonString.Append("{");
-                for (int j = 0; j < dt.Columns.Count; j++)
-                {
-                    string strKey = dt.Columns[j].ColumnName;
-                    string strValue = drc[i][j].ToString();
-                    Type type = dt.Columns[j].DataType;
-                    jsonString.Append("\"" + strKey + "\":");
-                    strValue = StringFormat(strValue, type);
-                    if (j < dt.Columns.Count - 1)
-                    {
-                        jsonString.Append(strValue + ",");
-                    }
-                    else
-                    {
-                        jsonString.Append(strValue);
-                    }
-                }
-                jsonString.Append("},");
-            }
-            jsonString.Remove(jsonString.Length - 1, 1);
-            jsonString.Append("]");
-            return jsonString.ToString();
-        }
-
-        /// <summary>
-        /// DataTable转换为Json 
-        /// </summary>
-        public static string ToJson(DataTable dt, string jsonName)
-        {
-            StringBuilder Json = new StringBuilder();
-            if (string.IsNullOrEmpty(jsonName)) jsonName = dt.TableName;
-            Json.Append("{\"" + jsonName + "\":[");
-            if (dt.Rows.Count > 0)
-            {
-                for (int i = 0; i < dt.Rows.Count; i++)
-                {
-                    Json.Append("{");
-                    for (int j = 0; j < dt.Columns.Count; j++)
-                    {
-                        Type type = dt.Rows[i][j].GetType();
-                        Json.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + StringFormat(dt.Rows[i][j].ToString(), type));
-                        if (j < dt.Columns.Count - 1)
-                        {
-                            Json.Append(",");
-                        }
-                    }
-                    Json.Append("}");
-                    if (i < dt.Rows.Count - 1)
-                    {
-                        Json.Append(",");
-                    }
-                }
-            }
-            Json.Append("]}");
-            return Json.ToString();
-        }
-        #endregion
-
-        #region DataReader转换为Json
-        /// <summary> 
-        /// DataReader转换为Json 
-        /// </summary> 
-        /// <param name="dataReader">DataReader对象</param> 
-        /// <returns>Json字符串</returns> 
-        public static string ToJson(DbDataReader dataReader)
-        {
-            StringBuilder jsonString = new StringBuilder();
-            jsonString.Append("[");
-            while (dataReader.Read())
-            {
-                jsonString.Append("{");
-                for (int i = 0; i < dataReader.FieldCount; i++)
-                {
-                    Type type = dataReader.GetFieldType(i);
-                    string strKey = dataReader.GetName(i);
-                    string strValue = dataReader[i].ToString();
-                    jsonString.Append("\"" + strKey + "\":");
-                    strValue = StringFormat(strValue, type);
-                    if (i < dataReader.FieldCount - 1)
-                    {
-                        jsonString.Append(strValue + ",");
-                    }
-                    else
-                    {
-                        jsonString.Append(strValue);
-                    }
-                }
-                jsonString.Append("},");
-            }
-            dataReader.Close();
-            jsonString.Remove(jsonString.Length - 1, 1);
-            jsonString.Append("]");
-            return jsonString.ToString();
-        }
-        #endregion
-    }
-}

+ 0 - 48
Azylee.Utils/Azylee.Core.Plus/DataUtils/JsonUtils/JsonTool.cs

@@ -1,48 +0,0 @@
-//************************************************************************
-//      https://github.com/yuzhengyang
-//      author:     yuzhengyang
-//      date:       2017.3.29 - 2017.8.24
-//      desc:       Json转换工具类(需要Newtonsoft.Json支持)
-//      Copyright (c) yuzhengyang. All rights reserved.
-//************************************************************************
-using Azylee.Core.IOUtils.TxtUtils;
-using Newtonsoft.Json;
-using System; 
-
-namespace Azylee.Core.Plus.DataUtils.JsonUtils
-{
-    public class JsonTool
-    {
-        public static string ToStr(object value)
-        {
-            return JsonConvert.SerializeObject(value);
-        }
-        public static object ToObjFromStr(string str)
-        {
-            string json = str;
-            if (!string.IsNullOrWhiteSpace(json))
-            {
-                try { return JsonConvert.DeserializeObject(json); } catch (Exception e) { }
-            }
-            return null;
-        }
-        public static T ToObjFromStr<T>(string str)
-        {
-            string json = str;
-            if (!string.IsNullOrWhiteSpace(json))
-            {
-                try { return JsonConvert.DeserializeObject<T>(json); } catch (Exception e) { }
-            }
-            return default(T);
-        }
-        public static T ToObjFromFile<T>(string file)
-        {
-            string json = TxtTool.Read(file);
-            if (!string.IsNullOrWhiteSpace(json))
-            {
-                try { return JsonConvert.DeserializeObject<T>(json); } catch (Exception e) { }
-            }
-            return default(T);
-        }
-    }
-}

+ 0 - 4
Azylee.Utils/Azylee.Core.Plus/packages.config

@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net40" />
-</packages>

+ 20 - 51
Azylee.Utils/Azylee.Core/AppUtils/AppLaunchTool.cs

@@ -1,6 +1,7 @@
 //************************************************************************
+//      https://github.com/yuzhengyang
 //      author:     yuzhengyang
-//      date:       2017.10.12 - 2017.10.12
+//      date:       2017.10.12 - 2018.10.24
 //      desc:       客户端启动器
 //      Copyright (c) yuzhengyang. All rights reserved.
 //************************************************************************
@@ -21,52 +22,20 @@ namespace Azylee.Core.AppUtils
         /// 启动最新版本程序
         /// </summary>
         /// <param name="route">路径:程序版本文件夹路径</param>
-        /// <param name="startfilename">可执行文件名</param>
+        /// <param name="exeFile">可执行文件名</param>
         /// <returns></returns>
-        public static bool StartNewVersion(string route, string startfilename)
+        public static bool StartNewVersion(string route, string exeFile)
         {
-            //判断路径是文件还是文件夹,并统一处理为文件夹
-            string appPath = route;
-            if (FileTool.IsFile(route))
-                appPath = DirTool.GetFilePath(route);
-
-            if (Directory.Exists(appPath))
+            if (GetNewVersion(route, exeFile, out Version version, out string startFile))
             {
-                //获取运行目录下所有文件
-                List<string> paths = DirTool.GetPath(appPath);
-                if (ListTool.HasElements(paths))
-                {
-                    //解析属于版本号的文件
-                    Version version = null;
-                    string startfile = null;
-                    foreach (var path in paths)
-                    {
-                        //只解析文件名带三个点的文件夹
-                        string filename = Path.GetFileName(path);
-                        if (StringTool.SubStringCount(filename, ".") == 3)
-                        {
-                            try
-                            {
-                                Version tempVersion = new Version(filename);
-                                string tempFile = DirTool.Combine(path, startfilename);
-                                if ((version == null || tempVersion > version) && File.Exists(tempFile))
-                                {
-                                    version = tempVersion;
-                                    startfile = tempFile;
-                                }
-                            }
-                            catch { }
-                        }
-                    }
-                    //准备启动
-                    if (startfile != null)
-                    {
-                        return ProcessTool.Start(startfile);
-                    }
-                }
+                return ProcessTool.Start(startFile);
             }
             return false;
         }
+        public static bool Start(string file)
+        {
+            return ProcessTool.Start(file);
+        }
         /// <summary>
         /// 查询是否有最新版本程序可以执行
         /// </summary>
@@ -111,13 +80,12 @@ namespace Azylee.Core.AppUtils
         /// 获取最新版本号
         /// </summary>
         /// <param name="route">路径:程序版本文件夹路径</param>
-        /// <param name="startfilename">可执行文件名</param>
+        /// <param name="exeFile">可执行文件名</param>
         /// <returns></returns>
-        public static Version GetNewVersion(string route, string startfilename)
+        public static bool GetNewVersion(string route, string exeFile, out Version version, out string startFile)
         {
-            //解析属于版本号的文件
-            Version version = null;
-            string startfile = null;
+            version = null;
+            startFile = "";
 
             //判断路径是文件还是文件夹,并统一处理为文件夹
             string appPath = route;
@@ -129,7 +97,7 @@ namespace Azylee.Core.AppUtils
                 //获取运行目录下所有文件
                 List<string> paths = DirTool.GetPath(appPath);
                 if (ListTool.HasElements(paths))
-                { 
+                {
                     foreach (var path in paths)
                     {
                         //只解析文件名带三个点的文件夹
@@ -139,19 +107,20 @@ namespace Azylee.Core.AppUtils
                             try
                             {
                                 Version tempVersion = new Version(filename);
-                                string tempFile = DirTool.Combine(path, startfilename);
+                                string tempFile = DirTool.Combine(path, exeFile);
                                 if ((version == null || tempVersion > version) && File.Exists(tempFile))
                                 {
                                     version = tempVersion;
-                                    startfile = tempFile;
+                                    startFile = tempFile;
                                 }
                             }
                             catch { }
                         }
-                    } 
+                    }
                 }
             }
-            return version;
+            if (version != null && Str.Ok(startFile)) return true;
+            return false;
         }
     }
 }

+ 1 - 1
Azylee.Utils/Azylee.Core/WindowsUtils/BrowserUtils/BrowserSelector.cs

@@ -38,7 +38,7 @@ namespace Azylee.Core.WindowsUtils.BrowserUtils
         }
 
         /// <summary>
-        /// 时期时代浏览器IE
+        /// 石器时代浏览器IE
         /// </summary>
         /// <param name="browser"></param>
         /// <returns></returns>

+ 16 - 0
Azylee.Utils/Azylee.Core/WindowsUtils/ConsoleUtils/Cons.cs

@@ -2,6 +2,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Runtime.InteropServices;
 using System.Text;
 
 namespace Azylee.Core.WindowsUtils.ConsoleUtils
@@ -103,5 +104,20 @@ namespace Azylee.Core.WindowsUtils.ConsoleUtils
             }
             catch { }
         }
+
+        #region Console 开启/关闭 API
+        /// <summary>
+        /// 启用系统控制台输出
+        /// </summary>
+        /// <returns></returns>
+        [DllImport("kernel32.dll")]
+        public static extern Boolean AllocConsole();
+        /// <summary>
+        /// 关闭系统控制台
+        /// </summary>
+        /// <returns></returns>
+        [DllImport("kernel32.dll")]
+        public static extern Boolean FreeConsole();
+        #endregion
     }
 }

+ 1 - 0
Azylee.Utils/Azylee.Jsons/Azylee.Jsons.csproj

@@ -20,6 +20,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Azylee.Jsons.xml</DocumentationFile>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>

+ 56 - 1
Azylee.Utils/Azylee.Jsons/Json.cs

@@ -1,22 +1,36 @@
 //************************************************************************
 //      https://github.com/yuzhengyang
 //      author:     yuzhengyang
-//      date:       2017.3.29 - 2017.8.24
+//      date:       2017.3.29 - 2018.10.19
 //      desc:       Json转换工具类(需要Newtonsoft.Json支持)
 //      Copyright (c) yuzhengyang. All rights reserved.
 //************************************************************************
 using Azylee.Core.IOUtils.TxtUtils;
 using Newtonsoft.Json;
 using System;
+using System.Text;
 
 namespace Azylee.Jsons
 {
+    /// <summary>
+    /// Json 工具
+    /// </summary>
     public class Json
     {
+        /// <summary>
+        /// 对象 转 字符串
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
         public static string Object2String(object obj)
         {
             return JsonConvert.SerializeObject(obj);
         }
+        /// <summary>
+        /// 字符串 转 对象
+        /// </summary>
+        /// <param name="s"></param>
+        /// <returns></returns>
         public static object String2Object(string s)
         {
             string json = s;
@@ -26,6 +40,12 @@ namespace Azylee.Jsons
             }
             return null;
         }
+        /// <summary>
+        /// 字符串 转 模型
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="s"></param>
+        /// <returns></returns>
         public static T String2Object<T>(string s)
         {
             string json = s;
@@ -35,6 +55,12 @@ namespace Azylee.Jsons
             }
             return default(T);
         }
+        /// <summary>
+        /// 读取文件文本 转 模型
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="file"></param>
+        /// <returns></returns>
         public static T File2Object<T>(string file)
         {
             string json = TxtTool.Read(file);
@@ -44,5 +70,34 @@ namespace Azylee.Jsons
             }
             return default(T);
         }
+        /// <summary>
+        /// 对象 转 字节(JSON中转)
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        public static byte[] Object2Byte(object obj)
+        {
+            try
+            {
+                string s = JsonConvert.SerializeObject(obj);
+                byte[] b = Encoding.UTF8.GetBytes(s);
+                return b;
+            }
+            catch { return null; }
+        }
+        /// <summary>
+        /// 字节 转 模型(JSON中转)
+        /// </summary>
+        /// <param name="b"></param>
+        /// <returns></returns>
+        public static T Byte2Object<T>(byte[] b)
+        {
+            try
+            {
+                string s = Encoding.UTF8.GetString(b);
+                return JsonConvert.DeserializeObject<T>(s);
+            }
+            catch { return default(T); }
+        }
     }
 }

+ 0 - 4
Azylee.Utils/Azylee.Update/Azylee.Update.csproj

@@ -46,10 +46,6 @@
     <Compile Include="UpdateUtils\AppUpdateTool.cs" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\Azylee.Core.Plus\Azylee.Core.Plus.csproj">
-      <Project>{915ae524-7efd-4ecc-b731-de1d1f5558f0}</Project>
-      <Name>Azylee.Core.Plus</Name>
-    </ProjectReference>
     <ProjectReference Include="..\Azylee.Core\Azylee.Core.csproj">
       <Project>{88dc61fa-95f0-41b7-9d7d-ab0f3cbd169c}</Project>
       <Name>Azylee.Core</Name>

+ 14 - 14
Azylee.Utils/Azylee.Utils.sln

@@ -9,8 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{927325CD
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azylee.Core", "Azylee.Core\Azylee.Core.csproj", "{88DC61FA-95F0-41B7-9D7D-AB0F3CBD169C}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azylee.Core.Plus", "Azylee.Core.Plus\Azylee.Core.Plus.csproj", "{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azylee.DB", "Azylee.DB\Azylee.DB.csproj", "{EF587677-DC59-4C46-B1AB-92904CD3F187}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azylee.ExeLaunch", "Azylee.ExeLaunch\Azylee.ExeLaunch.csproj", "{1AB11F85-BA96-4F82-8122-BB89E63FCCB1}"
@@ -23,8 +21,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azylee.YeahWeb", "Azylee.Ye
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9351FC10-E8D0-41BB-A813-0B5B3EA90605}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.ProcessTool", "Tests\Test.ProcessTool\Test.ProcessTool.csproj", "{5FB93D25-8855-4A80-9E08-131BC728B7F4}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.YeahWeb", "Tests\Test.YeahWeb\Test.YeahWeb.csproj", "{0213B9D4-1B4A-4BDE-9CE9-228C68A9A522}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azylee.DB.SQLite", "Azylee.DB.SQLite\Azylee.DB.SQLite.csproj", "{A77DBB5D-CA37-425C-8FA2-8B0736AE1C4D}"
@@ -33,6 +29,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Toast", "Tests\Test.To
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azylee.Jsons", "Azylee.Jsons\Azylee.Jsons.csproj", "{DE3AB999-96D3-4A53-A9F2-7409138D0333}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.TcpServerApp", "Tests\Test.TcpServerApp\Test.TcpServerApp.csproj", "{BF8291F5-3737-49EA-872B-07068D8AD4F0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.TcpClientApp", "Tests\Test.TcpClientApp\Test.TcpClientApp.csproj", "{B251E246-9F9C-4AEC-9748-FBCFAD2381E1}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -47,10 +47,6 @@ Global
 		{88DC61FA-95F0-41B7-9D7D-AB0F3CBD169C}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{88DC61FA-95F0-41B7-9D7D-AB0F3CBD169C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{88DC61FA-95F0-41B7-9D7D-AB0F3CBD169C}.Release|Any CPU.Build.0 = Release|Any CPU
-		{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{915AE524-7EFD-4ECC-B731-DE1D1F5558F0}.Release|Any CPU.Build.0 = Release|Any CPU
 		{EF587677-DC59-4C46-B1AB-92904CD3F187}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{EF587677-DC59-4C46-B1AB-92904CD3F187}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{EF587677-DC59-4C46-B1AB-92904CD3F187}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -71,10 +67,6 @@ Global
 		{CCF7A654-B442-4DB1-BB3B-0F8014C3237F}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{CCF7A654-B442-4DB1-BB3B-0F8014C3237F}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{CCF7A654-B442-4DB1-BB3B-0F8014C3237F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{5FB93D25-8855-4A80-9E08-131BC728B7F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{5FB93D25-8855-4A80-9E08-131BC728B7F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{5FB93D25-8855-4A80-9E08-131BC728B7F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{5FB93D25-8855-4A80-9E08-131BC728B7F4}.Release|Any CPU.Build.0 = Release|Any CPU
 		{0213B9D4-1B4A-4BDE-9CE9-228C68A9A522}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{0213B9D4-1B4A-4BDE-9CE9-228C68A9A522}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{0213B9D4-1B4A-4BDE-9CE9-228C68A9A522}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -91,23 +83,31 @@ Global
 		{DE3AB999-96D3-4A53-A9F2-7409138D0333}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{DE3AB999-96D3-4A53-A9F2-7409138D0333}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{DE3AB999-96D3-4A53-A9F2-7409138D0333}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BF8291F5-3737-49EA-872B-07068D8AD4F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BF8291F5-3737-49EA-872B-07068D8AD4F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BF8291F5-3737-49EA-872B-07068D8AD4F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BF8291F5-3737-49EA-872B-07068D8AD4F0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B251E246-9F9C-4AEC-9748-FBCFAD2381E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B251E246-9F9C-4AEC-9748-FBCFAD2381E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B251E246-9F9C-4AEC-9748-FBCFAD2381E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B251E246-9F9C-4AEC-9748-FBCFAD2381E1}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
 		{88DC61FA-95F0-41B7-9D7D-AB0F3CBD169C} = {927325CD-24FD-4B85-A982-543D4F58A47C}
-		{915AE524-7EFD-4ECC-B731-DE1D1F5558F0} = {927325CD-24FD-4B85-A982-543D4F58A47C}
 		{EF587677-DC59-4C46-B1AB-92904CD3F187} = {927325CD-24FD-4B85-A982-543D4F58A47C}
 		{1AB11F85-BA96-4F82-8122-BB89E63FCCB1} = {927325CD-24FD-4B85-A982-543D4F58A47C}
 		{76F92BAE-8C9C-42AA-85E8-51F2EA8A0C91} = {927325CD-24FD-4B85-A982-543D4F58A47C}
 		{D280C16F-FDE2-4647-BD76-3514F673426D} = {927325CD-24FD-4B85-A982-543D4F58A47C}
 		{CCF7A654-B442-4DB1-BB3B-0F8014C3237F} = {927325CD-24FD-4B85-A982-543D4F58A47C}
-		{5FB93D25-8855-4A80-9E08-131BC728B7F4} = {9351FC10-E8D0-41BB-A813-0B5B3EA90605}
 		{0213B9D4-1B4A-4BDE-9CE9-228C68A9A522} = {9351FC10-E8D0-41BB-A813-0B5B3EA90605}
 		{A77DBB5D-CA37-425C-8FA2-8B0736AE1C4D} = {927325CD-24FD-4B85-A982-543D4F58A47C}
 		{576CFDD2-150A-4D0C-874A-730265537902} = {9351FC10-E8D0-41BB-A813-0B5B3EA90605}
 		{DE3AB999-96D3-4A53-A9F2-7409138D0333} = {927325CD-24FD-4B85-A982-543D4F58A47C}
+		{BF8291F5-3737-49EA-872B-07068D8AD4F0} = {9351FC10-E8D0-41BB-A813-0B5B3EA90605}
+		{B251E246-9F9C-4AEC-9748-FBCFAD2381E1} = {9351FC10-E8D0-41BB-A813-0B5B3EA90605}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {3A021A3E-4C98-47CD-B4E8-912E12611C2E}

+ 8 - 0
Azylee.Utils/Azylee.YeahWeb/Azylee.YeahWeb.csproj

@@ -20,6 +20,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Azylee.YeahWeb.xml</DocumentationFile>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
@@ -60,6 +61,13 @@
     <Compile Include="HttpUtils\Models\UserAgents.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="SocketUtils\SocketTool.cs" />
+    <Compile Include="SocketUtils\TcpUtils\TcpClientDictionary.cs" />
+    <Compile Include="SocketUtils\TcpUtils\TcppClient.cs" />
+    <Compile Include="SocketUtils\TcpUtils\TcpDataConverter.cs" />
+    <Compile Include="SocketUtils\TcpUtils\TcpDataModel.cs" />
+    <Compile Include="SocketUtils\TcpUtils\TcppServer.cs" />
+    <Compile Include="SocketUtils\TcpUtils\TcpDelegate.cs" />
+    <Compile Include="SocketUtils\TcpUtils\TcpStreamHelper.cs" />
     <Compile Include="TencentWebAPI\PictureAI\PictureScener.cs" />
   </ItemGroup>
   <ItemGroup>

+ 14 - 0
Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpClientDictionary.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+
+namespace Azylee.YeahWeb.SocketUtils.TcpUtils
+{
+    public class TcpClientDictionary
+    {
+        public string Host { get; set; }
+        public TcpClient Client { get; set; }
+    }
+}

+ 42 - 0
Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpDataConverter.cs

@@ -0,0 +1,42 @@
+using Azylee.Core.WindowsUtils.ConsoleUtils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Azylee.YeahWeb.SocketUtils.TcpUtils
+{
+    public static class TcpDataConverter
+    {
+        const int HeadLength = 4 + 4 + 4;
+        const int ReceiveBufferSize = 1024;
+        public static int Byte2Model(List<byte> data, out TcpDataModel model)
+        {
+            model = null;
+
+            if (data.Count > HeadLength &&
+                data[0] == 111 && data[1] == 222 && data[2] == 66 && data[3] == 66)
+            {
+                int msgCode = BitConverter.ToInt32(new byte[] { data[4], data[5], data[6], data[7] }, 0);
+                int msgBodyLength = BitConverter.ToInt32(new byte[] { data[8], data[9], data[10], data[11] }, 0);
+                if (data.Count >= HeadLength + msgBodyLength)
+                {
+                    byte[] body = data.GetRange(HeadLength, msgBodyLength).ToArray();
+                    string bodyToGBK = Encoding.GetEncoding("GBK").GetString(body);
+                    //ReceiveByteContent(body);
+                    Cons.Log(bodyToGBK);
+                    //Send(ReceiveByte.GetRange(0, 6).ToArray());
+                    data.RemoveRange(0, 6 + msgBodyLength);
+
+                    //ReceiveMessage?.Invoke(msgCode, body);
+                }
+            }
+            else
+            {
+                data.Clear();
+                //Socket.Send(new byte[] { 0 });
+            }
+            return 0;
+        }
+    }
+}

+ 67 - 0
Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpDataModel.cs

@@ -0,0 +1,67 @@
+using Azylee.Core.DataUtils.SerializeUtils;
+using Azylee.Core.WindowsUtils.ConsoleUtils;
+using Azylee.Jsons;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Azylee.YeahWeb.SocketUtils.TcpUtils
+{
+    /// <summary>
+    /// Tcp 传输数据模型
+    /// </summary>
+    public class TcpDataModel
+    {
+        /// <summary>
+        /// 类型
+        /// </summary>
+        public int Type { get; set; }
+        /// <summary>
+        /// 数据
+        /// </summary>
+        public byte[] Data { get; set; }
+        /// <summary>
+        /// 转换为 byte 数组
+        /// </summary>
+        /// <returns></returns>
+        public byte[] ToByte()
+        {
+            List<byte> result = new List<byte>();
+            result.AddRange(BitConverter.GetBytes(Type));
+            if (Data != null)
+            {
+                result.AddRange(BitConverter.GetBytes((int)Data.Length));
+                result.AddRange(Data);
+            }
+            else
+            {
+                result.AddRange(BitConverter.GetBytes((int)0));
+                result.AddRange(new byte[] { });
+            }
+            return result.ToArray();
+        }
+        /// <summary>
+        /// 转换为模型
+        /// </summary>
+        /// <param name="bytes"></param>
+        /// <returns></returns>
+        public static TcpDataModel ToModel(byte[] bytes)
+        {
+            TcpDataModel model = null;
+            try
+            {
+                int type = BitConverter.ToInt32(bytes, 0);
+                int length = BitConverter.ToInt32(bytes, 4);
+
+                byte[] data_byte = bytes.Skip(8).Take(length).ToArray();
+
+                model = new TcpDataModel();
+                model.Type = type;
+                model.Data = data_byte;
+            }
+            catch { }
+            return model;
+        }
+    }
+}

+ 30 - 0
Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpDelegate.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Azylee.YeahWeb.SocketUtils.TcpUtils
+{
+    /// <summary>
+    /// Tcp 工具 委托声明
+    /// </summary>
+    public class TcpDelegate
+    {
+        /// <summary>
+        /// 接受消息委托
+        /// </summary>
+        /// <param name="host"></param>
+        /// <param name="model"></param>
+        public delegate void ReceiveMessage(string host, TcpDataModel model);
+        /// <summary>
+        /// Tcp 连接消息委托
+        /// </summary>
+        /// <param name="host"></param>
+        public delegate void OnConnect(string host);
+        /// <summary>
+        /// Tcp 断开连接消息委托
+        /// </summary>
+        /// <param name="host"></param>
+        public delegate void OnDisconnect(string host);
+    }
+}

+ 95 - 0
Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcpStreamHelper.cs

@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+
+namespace Azylee.YeahWeb.SocketUtils.TcpUtils
+{
+    /// <summary>
+    /// Tcp 流数据处理辅助类
+    /// </summary>
+    public class TcpStreamHelper
+    {
+        const int ReceiveBufferSize = 1024;
+        /// <summary>
+        /// 流 写入
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="model"></param>
+        /// <returns></returns>
+        public static bool Write(TcpClient client, TcpDataModel model)
+        {
+            try
+            {
+                if (client != null && client.GetStream() != null)
+                {
+                    byte[] md_byte = model.ToByte();
+                    byte[] length_byte = BitConverter.GetBytes((int)(md_byte.Length + 4));
+
+                    List<byte> data = new List<byte>();
+                    data.AddRange(length_byte);//长度
+                    data.AddRange(new byte[] { 111, 222, 66, 66 });//标志
+                    data.AddRange(md_byte);//内容
+
+                    client.GetStream().Write(data.ToArray(), 0, data.Count);//写出内容
+                    return true;
+                }
+            }
+            catch { }
+            return false;
+        }
+        /// <summary>
+        /// 流 读取
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <returns></returns>
+        public static TcpDataModel Read(TcpClient client)
+        {
+            TcpDataModel data = null;
+            try
+            {
+                if (client != null && client.GetStream() != null)
+                {
+                    //内容长度
+                    byte[] data_length = new byte[4];
+                    int read = client.GetStream().Read(data_length, 0, 4);
+                    int length = BitConverter.ToInt32(data_length, 0) - 4;
+
+                    if (read > 0 && length > 0)
+                    {
+                        //内容头部标志
+                        byte[] data_head = new byte[4];
+                        client.GetStream().Read(data_head, 0, 4);
+                        bool head = data_head[0] == 111 && data_head[1] == 222 && data_head[2] == 66 && data_head[3] == 66;
+
+                        if (head)
+                        {
+                            //读取内容
+                            byte[] buffer = new byte[length];
+                            int bf_read = 0;
+                            while (bf_read < length)
+                            {
+                                //循环读取内容,防止断包
+                                bf_read += client.GetStream().Read(buffer, bf_read, length - bf_read);
+                                if (bf_read < length)
+                                {
+                                    int x = bf_read;
+                                }
+                            }
+                            //解析内容
+                            data = TcpDataModel.ToModel(buffer);
+                        }
+                    }
+                    else
+                    {
+                        if (read == 0)
+                            client?.Close();
+                    }
+                }
+            }
+            catch { }
+            return data;
+        }
+    }
+}

+ 153 - 0
Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcppClient.cs

@@ -0,0 +1,153 @@
+using Azylee.Core.ThreadUtils.SleepUtils;
+using Azylee.Core.WindowsUtils.ConsoleUtils;
+using Azylee.Jsons;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Azylee.YeahWeb.SocketUtils.TcpUtils
+{
+    public class TcppClient
+    {
+        const int ReceiveBufferSize = 1024;
+        private string _IP = "";
+        private int _Port = 52801;
+        private TcpClient Client = null;
+        private NetworkStream networkStream = null;
+
+        TcpDelegate.ReceiveMessage ReceiveMessage;
+        TcpDelegate.OnConnect OnConnect;
+        TcpDelegate.OnDisconnect OnDisconnect;
+
+        //public TcpDataConverter.Message ReceiveMessage;
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="ip"></param>
+        /// <param name="port"></param>
+        public TcppClient(string ip, int port,
+            TcpDelegate.ReceiveMessage receive,
+              TcpDelegate.OnConnect connect,
+               TcpDelegate.OnDisconnect disconnect)
+        {
+            this._IP = ip;
+            this._Port = port;
+
+            ReceiveMessage += receive;
+            OnConnect += connect;
+            OnDisconnect += disconnect;
+        }
+
+        #region 连接和关闭连接
+        /// <summary>
+        /// 连接到TcpServer(重连)
+        /// </summary>
+        public bool Connect()
+        {
+            try
+            {
+                if (this.Client == null || !this.Client.Connected)
+                {
+                    this.Client = new TcpClient();
+                    //this.Read();
+                    IAsyncResult ar = this.Client.BeginConnect(this._IP, this._Port, acceptCallback, this.Client);
+                    bool isConnect = ar.AsyncWaitHandle.WaitOne(1000);
+                    if (isConnect) return true;
+                }
+            }
+            catch { }
+            return false;
+        }
+        /// <summary>
+        /// 关闭连接
+        /// </summary>
+        public void Disconnect()
+        {
+            networkStream?.Close();
+            Client?.Close();
+        }
+        #endregion
+
+        #region 连接后的读写操作
+        /// <summary>
+        /// 发送数据
+        /// </summary>
+        /// <param name="model">数据模型</param>
+        public void Write(TcpDataModel model)
+        {
+            if (this.Client != null && this.Client.Connected)
+            {
+                bool flag = TcpStreamHelper.Write(Client, model);
+            }
+        }
+        /// <summary>
+        /// 发送数据
+        /// </summary>
+        /// <param name="type">类型</param>
+        /// <param name="data">数据</param>
+        public void Write(int type, byte[] data)
+        {
+            Write(new TcpDataModel() { Type = type, Data = data });
+        }
+        /// <summary>
+        /// 发送数据
+        /// </summary>
+        /// <param name="type">类型</param>
+        /// <param name="s">字符串</param>
+        public void Write(int type, string s)
+        {
+            Write(new TcpDataModel() { Type = type, Data = Json.Object2Byte(s) });
+        }
+        /// <summary>
+        /// 接受数据
+        /// </summary>
+        private void acceptCallback(IAsyncResult state)
+        {
+            try
+            {
+                this.Client = (TcpClient)state.AsyncState;
+                this.Client.EndConnect(state);
+
+                string host = this.Client.Client.RemoteEndPoint.ToString();
+                ConnectTask(host, this.Client);
+            }
+            catch { }
+        }
+        private void ConnectTask(string host, TcpClient client)
+        {
+            Task.Factory.StartNew(() =>
+            {
+                OnConnect?.Invoke(host);//委托:已连接
+                while (client.Connected)
+                {
+                    try
+                    {
+                        TcpDataModel model = TcpStreamHelper.Read(client);
+                        if (model != null)
+                        {
+                            if (model.Type == int.MaxValue)
+                            {
+                                //返回心跳
+                                Write(new TcpDataModel() { Type = int.MaxValue });
+                            }
+                            else
+                            {
+                                ReceiveMessage(host, model);//委托:接收消息
+                            }
+                        }
+                    }
+                    catch { }
+                    //Sleep.S(1);
+                }
+                client.Close();
+                OnDisconnect?.Invoke(host);//委托:断开连接
+            });
+            //lstn.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), lstn);
+        }
+        #endregion
+    }
+}

+ 231 - 0
Azylee.Utils/Azylee.YeahWeb/SocketUtils/TcpUtils/TcppServer.cs

@@ -0,0 +1,231 @@
+using Azylee.Core.ThreadUtils.SleepUtils;
+using Azylee.Core.WindowsUtils.ConsoleUtils;
+using Azylee.Jsons;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Azylee.YeahWeb.SocketUtils.TcpUtils
+{
+    /// <summary>
+    /// Tcp 服务工具
+    /// </summary>
+    public class TcppServer
+    {
+        const int ReceiveBufferSize = 1024;
+        private List<byte> ReceiveByte = new List<byte>();
+        private int _Port = 52801;
+        TcpListener Listener = null;
+        TcpDelegate.ReceiveMessage ReceiveMessage;
+        TcpDelegate.OnConnect OnConnect;
+        TcpDelegate.OnDisconnect OnDisconnect;
+        List<TcpClientDictionary> Clients = new List<TcpClientDictionary>();
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="port">端口号</param>
+        /// <param name="receive">接收消息</param>
+        /// <param name="connect">连接动作</param>
+        /// <param name="disconnect">断开动作</param>
+        public TcppServer(int port,
+            TcpDelegate.ReceiveMessage receive,
+              TcpDelegate.OnConnect connect,
+               TcpDelegate.OnDisconnect disconnect)
+        {
+            _Port = port;
+
+            ReceiveMessage += receive;
+            OnConnect += connect;
+            OnDisconnect += disconnect;
+        }
+
+        #region 启动和停止服务
+        /// <summary>
+        /// 启动服务
+        /// </summary>
+        public void Start()
+        {
+            this.Listener = new TcpListener(IPAddress.Any, _Port);
+            this.Listener.Start();
+            this.Listener.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), this.Listener);
+        }
+        /// <summary>
+        /// 停止服务
+        /// </summary>
+        public void Stop()
+        {
+            foreach (var client in Clients)
+            {
+                client?.Client?.Close();
+            }
+            Clients.Clear();
+            this.Listener?.Stop();
+        }
+        #endregion
+
+        #region 连接后的读写操作
+        /// <summary>
+        /// 发送数据
+        /// </summary>
+        /// <param name="host">主机地址</param>
+        /// <param name="model">数据模型</param>
+        public void Write(string host, TcpDataModel model)
+        {
+            var dictionary = Clients_Get(host);
+            if (dictionary != null && dictionary.Client != null)
+            {
+                if (dictionary.Client.Connected)
+                {
+                    bool flag = TcpStreamHelper.Write(dictionary.Client, model);
+                }
+            }
+        }
+        /// <summary>
+        /// 发送数据
+        /// </summary>
+        /// <param name="host">主机地址</param>
+        /// <param name="type">类型</param>
+        /// <param name="data">数据</param>
+        public void Write(string host, int type, byte[] data)
+        {
+            Write(host, new TcpDataModel() { Type = type, Data = data });
+        }
+        /// <summary>
+        /// 发送数据
+        /// </summary>
+        /// <param name="host">主机地址</param>
+        /// <param name="type">类型</param>
+        /// <param name="s">字符串</param>
+        public void Write(string host, int type, string s)
+        {
+            Write(host, new TcpDataModel() { Type = type, Data = Json.Object2Byte(s) });
+        }
+
+        private void acceptCallback(IAsyncResult state)
+        {
+            try
+            {
+                TcpListener lstn = (TcpListener)state.AsyncState;
+                TcpClient client = lstn.EndAcceptTcpClient(state);
+                string host = client.Client.RemoteEndPoint.ToString();
+
+                Clients_Add_Update(host, client);
+                ConnectTask(host, client);
+
+                lstn.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), lstn);
+            }
+            catch { }
+        }
+        private void ConnectTask(string host, TcpClient client)
+        {
+            DateTime HeartbeatTime = DateTime.Now;
+
+            //发送心跳
+            Task.Factory.StartNew(() =>
+            {
+                while (client.Connected)
+                {
+                    TcpDataModel model = new TcpDataModel() { Type = int.MaxValue };
+                    TcpStreamHelper.Write(client, model);
+
+                    Sleep.S(5);
+                    //if (DateTime.Now.AddSeconds(-10) > HeartbeatTime)
+                    //    client.Close();
+                    Sleep.S(5);
+                }
+            });
+            //接收消息
+            Task.Factory.StartNew(() =>
+            {
+                OnConnect?.Invoke(host);//委托:已连接
+                while (client.Connected)
+                {
+                    try
+                    {
+                        TcpDataModel model = TcpStreamHelper.Read(client);
+                        if (model != null)
+                        {
+                            if (model.Type == int.MaxValue)
+                            {
+                                //过滤心跳
+                                HeartbeatTime = DateTime.Now;
+                            }
+                            else
+                            {
+                                ReceiveMessage(host, model);//委托:接收消息
+                            }
+                        }
+                    }
+                    catch { }
+                    //Sleep.S(1);
+                }
+                client.Close();
+                Clients_Del(host);
+                OnDisconnect?.Invoke(host);//委托:断开连接
+            });
+        }
+        #endregion
+
+        #region 连接的客户端列表维护
+        /// <summary>
+        /// 获取连接的客户端
+        /// </summary>
+        /// <returns></returns>
+        private TcpClientDictionary Clients_Get(string host)
+        {
+            TcpClientDictionary client = null;
+            try
+            {
+                client = Clients.FirstOrDefault(x => x.Host == host);
+            }
+            catch { }
+            return client;
+        }
+        /// <summary>
+        /// 添加或更新到客户端列表
+        /// </summary>
+        private void Clients_Add_Update(string host, TcpClient client)
+        {
+            try
+            {
+                var item = Clients.FirstOrDefault(x => x.Host == host);
+                if (item == null)
+                {
+                    Clients.Add(new TcpClientDictionary() { Host = host, Client = client });
+                }
+                else
+                {
+                    item.Client = client;
+                }
+            }
+            catch { }
+        }
+        /// <summary>
+        /// 从客户端列表中删除
+        /// </summary>
+        private int Clients_Del(string host)
+        {
+            int count = 0;
+            try
+            {
+                count = Clients.RemoveAll(x => x.Host == host);
+            }
+            catch { }
+            return count;
+        }
+        /// <summary>
+        /// 当前连接客户端总数
+        /// </summary>
+        /// <returns></returns>
+        public int ClientsCount()
+        {
+            return Clients.Count();
+        }
+        #endregion
+    }
+}

+ 0 - 49
Azylee.Utils/Tests/Test.ProcessTool/Program.cs

@@ -1,49 +0,0 @@
-using Azylee.Core.AppUtils;
-using Azylee.Core.LogUtils.SimpleLogUtils;
-using Azylee.Core.ThreadUtils.SleepUtils;
-using Azylee.Core.WindowsUtils.ConsoleUtils;
-using Azylee.Core.WindowsUtils.ShortcutUtils;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Test.ProcessTool
-{
-    class Program
-    {
-        static void Main(string[] args)
-        {
-            Log log = new Log(LogLevel.All, LogLevel.Information);
-
-            Cons.Log("测试 Default 测试");
-            log.V<string>(null);
-            Cons.Log("测试 Muted 测试\r\n\r\n测试 Muted 测试\r\n\r\n测试 Muted 测试\r\n\r\n测试 Muted 测试", ConsColorMode.Muted);
-            log.V("测试 Log V \r\n\r\n 测试 Log V \r\n\r\n 测试 Log V \r\n\r\n");
-
-            Cons.Log("测试 Muted 测试\r\n\r\n测试 Muted 测试\r\n\r\n测试 Muted 测试\r\n\r\n测试 Muted 测试", ConsColorMode.Muted);
-            log.I("测试 Log V \r\n\r\n 测试 Log V \r\n\r\n 测试 Log V \r\n\r\n");
-
-            Cons.Log("测试 Muted 测试\r\r测试 Muted 测试\r\r测试 Muted 测试\r\r测试 Muted 测试", ConsColorMode.Muted);
-            log.I("测试 Log V \r\r 测试 Log V \r\r 测试 Log V \r\r");
-
-            Cons.Log("测试 Muted 测试\n\n测试 Muted 测试\n\n测试 Muted 测试\n\n测试 Muted 测试", ConsColorMode.Muted);
-            log.I("测试 Log V \n\n 测试 Log V \n\n 测试 Log V \n\n");
-
-            Cons.Log("测试 Primary 测试", ConsColorMode.Primary);
-            Cons.Log("测试 Secondary 测试", ConsColorMode.Secondary);
-            Cons.Log("测试 Success 测试", ConsColorMode.Success);
-            Cons.Log("测试 Info 测试", ConsColorMode.Info);
-            Cons.Log("测试 Warning 测试", ConsColorMode.Warning);
-            Cons.Log("测试 Danger 测试", ConsColorMode.Danger);
-            Cons.Log("测试 Dark 测试", ConsColorMode.Dark);
-            Cons.Log("测试 Light 测试", ConsColorMode.Light);
-
-            Console.WriteLine();
-            Console.WriteLine("====================");
-            Console.WriteLine("====================");
-            Console.ReadLine();
-            //Azylee.Core.ProcessUtils.ProcessTool.Start("CPAU.EXE","-u Zephyr -p 123456 ");
-        }
-    }
-}

+ 201 - 0
Azylee.Utils/Tests/Test.TcpClientApp/MainForm.Designer.cs

@@ -0,0 +1,201 @@
+namespace Test.TcpClientApp
+{
+    partial class MainForm
+    {
+        /// <summary>
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows 窗体设计器生成的代码
+
+        /// <summary>
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.BTDisconnect = new System.Windows.Forms.Button();
+            this.TBPort = new System.Windows.Forms.TextBox();
+            this.TBText = new System.Windows.Forms.TextBox();
+            this.BTConnect = new System.Windows.Forms.Button();
+            this.TBType = new System.Windows.Forms.TextBox();
+            this.TBMessage = new System.Windows.Forms.TextBox();
+            this.BTSend = new System.Windows.Forms.Button();
+            this.TBIP = new System.Windows.Forms.TextBox();
+            this.LBTextLength = new System.Windows.Forms.Label();
+            this.LBMessageLength = new System.Windows.Forms.Label();
+            this.LBLine1 = new System.Windows.Forms.Label();
+            this.BTClear = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // BTDisconnect
+            // 
+            this.BTDisconnect.Location = new System.Drawing.Point(259, 8);
+            this.BTDisconnect.Name = "BTDisconnect";
+            this.BTDisconnect.Size = new System.Drawing.Size(69, 23);
+            this.BTDisconnect.TabIndex = 7;
+            this.BTDisconnect.Text = "断开";
+            this.BTDisconnect.UseVisualStyleBackColor = true;
+            this.BTDisconnect.Click += new System.EventHandler(this.BTDisconnect_Click);
+            // 
+            // TBPort
+            // 
+            this.TBPort.Location = new System.Drawing.Point(128, 10);
+            this.TBPort.Name = "TBPort";
+            this.TBPort.Size = new System.Drawing.Size(50, 21);
+            this.TBPort.TabIndex = 6;
+            this.TBPort.Text = "52801";
+            // 
+            // TBText
+            // 
+            this.TBText.Enabled = false;
+            this.TBText.Location = new System.Drawing.Point(12, 37);
+            this.TBText.Multiline = true;
+            this.TBText.Name = "TBText";
+            this.TBText.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+            this.TBText.Size = new System.Drawing.Size(397, 75);
+            this.TBText.TabIndex = 5;
+            this.TBText.TextChanged += new System.EventHandler(this.TBText_TextChanged);
+            // 
+            // BTConnect
+            // 
+            this.BTConnect.Location = new System.Drawing.Point(184, 8);
+            this.BTConnect.Name = "BTConnect";
+            this.BTConnect.Size = new System.Drawing.Size(69, 23);
+            this.BTConnect.TabIndex = 4;
+            this.BTConnect.Text = "连接";
+            this.BTConnect.UseVisualStyleBackColor = true;
+            this.BTConnect.Click += new System.EventHandler(this.BTConnect_Click);
+            // 
+            // TBType
+            // 
+            this.TBType.Location = new System.Drawing.Point(447, 8);
+            this.TBType.Name = "TBType";
+            this.TBType.Size = new System.Drawing.Size(55, 21);
+            this.TBType.TabIndex = 8;
+            this.TBType.Text = "1000";
+            // 
+            // TBMessage
+            // 
+            this.TBMessage.Location = new System.Drawing.Point(447, 35);
+            this.TBMessage.Multiline = true;
+            this.TBMessage.Name = "TBMessage";
+            this.TBMessage.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+            this.TBMessage.Size = new System.Drawing.Size(139, 77);
+            this.TBMessage.TabIndex = 9;
+            this.TBMessage.TextChanged += new System.EventHandler(this.TBMessage_TextChanged);
+            // 
+            // BTSend
+            // 
+            this.BTSend.Location = new System.Drawing.Point(517, 6);
+            this.BTSend.Name = "BTSend";
+            this.BTSend.Size = new System.Drawing.Size(69, 23);
+            this.BTSend.TabIndex = 10;
+            this.BTSend.Text = "发送";
+            this.BTSend.UseVisualStyleBackColor = true;
+            this.BTSend.Click += new System.EventHandler(this.BTSend_Click);
+            // 
+            // TBIP
+            // 
+            this.TBIP.Location = new System.Drawing.Point(12, 10);
+            this.TBIP.Name = "TBIP";
+            this.TBIP.Size = new System.Drawing.Size(109, 21);
+            this.TBIP.TabIndex = 11;
+            this.TBIP.Text = "127.0.0.1";
+            // 
+            // LBTextLength
+            // 
+            this.LBTextLength.AutoSize = true;
+            this.LBTextLength.Location = new System.Drawing.Point(12, 115);
+            this.LBTextLength.Name = "LBTextLength";
+            this.LBTextLength.Size = new System.Drawing.Size(11, 12);
+            this.LBTextLength.TabIndex = 12;
+            this.LBTextLength.Text = "0";
+            // 
+            // LBMessageLength
+            // 
+            this.LBMessageLength.AutoSize = true;
+            this.LBMessageLength.Location = new System.Drawing.Point(445, 115);
+            this.LBMessageLength.Name = "LBMessageLength";
+            this.LBMessageLength.Size = new System.Drawing.Size(11, 12);
+            this.LBMessageLength.TabIndex = 13;
+            this.LBMessageLength.Text = "0";
+            // 
+            // LBLine1
+            // 
+            this.LBLine1.BackColor = System.Drawing.Color.Black;
+            this.LBLine1.Location = new System.Drawing.Point(427, 8);
+            this.LBLine1.Name = "LBLine1";
+            this.LBLine1.Size = new System.Drawing.Size(1, 106);
+            this.LBLine1.TabIndex = 14;
+            // 
+            // BTClear
+            // 
+            this.BTClear.Location = new System.Drawing.Point(340, 6);
+            this.BTClear.Name = "BTClear";
+            this.BTClear.Size = new System.Drawing.Size(69, 23);
+            this.BTClear.TabIndex = 15;
+            this.BTClear.Text = "清空";
+            this.BTClear.UseVisualStyleBackColor = true;
+            this.BTClear.Click += new System.EventHandler(this.BTClear_Click);
+            // 
+            // MainForm
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(610, 136);
+            this.Controls.Add(this.BTClear);
+            this.Controls.Add(this.LBLine1);
+            this.Controls.Add(this.LBMessageLength);
+            this.Controls.Add(this.LBTextLength);
+            this.Controls.Add(this.TBIP);
+            this.Controls.Add(this.BTSend);
+            this.Controls.Add(this.TBMessage);
+            this.Controls.Add(this.TBType);
+            this.Controls.Add(this.BTDisconnect);
+            this.Controls.Add(this.TBPort);
+            this.Controls.Add(this.TBText);
+            this.Controls.Add(this.BTConnect);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
+            this.Name = "MainForm";
+            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+            this.Text = "Tcp客户端";
+            this.Load += new System.EventHandler(this.MainForm_Load);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Button BTDisconnect;
+        private System.Windows.Forms.TextBox TBPort;
+        private System.Windows.Forms.TextBox TBText;
+        private System.Windows.Forms.Button BTConnect;
+        private System.Windows.Forms.TextBox TBType;
+        private System.Windows.Forms.TextBox TBMessage;
+        private System.Windows.Forms.Button BTSend;
+        private System.Windows.Forms.TextBox TBIP;
+        private System.Windows.Forms.Label LBTextLength;
+        private System.Windows.Forms.Label LBMessageLength;
+        private System.Windows.Forms.Label LBLine1;
+        private System.Windows.Forms.Button BTClear;
+    }
+}
+

+ 93 - 0
Azylee.Utils/Tests/Test.TcpClientApp/MainForm.cs

@@ -0,0 +1,93 @@
+using Azylee.YeahWeb.SocketUtils.TcpUtils;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Test.TcpClientApp
+{
+    public partial class MainForm : Form
+    {
+        TcppClient tcpClient = null;
+        public MainForm()
+        {
+            InitializeComponent();
+        }
+
+        private void BTConnect_Click(object sender, EventArgs e)
+        {
+            tcpClient = new TcppClient(TBIP.Text, int.Parse(TBPort.Text),
+                     ReceiveMessage, OnConnect, OnDisconnect);
+            bool flag = tcpClient.Connect();
+            if (flag) MessageBox.Show("连接成功");
+            else MessageBox.Show("连接失败");
+        }
+        private void OnConnect(string host)
+        {
+            this.Invoke(new Action(() =>
+            {
+                TBText.AppendText($"Connect : {host}" + Environment.NewLine);
+            }));
+        }
+        private void OnDisconnect(string host)
+        {
+            this.Invoke(new Action(() =>
+            {
+                TBText.AppendText($"Disconnect : {host}" + Environment.NewLine);
+            }));
+        }
+        private void ReceiveMessage(string host, TcpDataModel data)
+        {
+            this.Invoke(new Action(() =>
+            {
+                if (data.Type == 1000)
+                {
+                    string s = Encoding.UTF8.GetString(data.Data);
+                    int l = s.Length;
+                    TBText.AppendText(host + " : " + s);
+                    TBText.AppendText(Environment.NewLine);
+                }
+            }));
+        }
+
+        private void BTSend_Click(object sender, EventArgs e)
+        {
+            byte[] sb = Encoding.UTF8.GetBytes(TBMessage.Text);
+            tcpClient.Write(new TcpDataModel()
+            {
+                Type = 1000,
+                Data = Encoding.UTF8.GetBytes(TBMessage.Text)
+            });
+        }
+
+        private void BTDisconnect_Click(object sender, EventArgs e)
+        {
+            tcpClient?.Disconnect();
+        }
+
+        private void TBText_TextChanged(object sender, EventArgs e)
+        {
+            LBTextLength.Text = TBText.TextLength.ToString();
+        }
+
+        private void TBMessage_TextChanged(object sender, EventArgs e)
+        {
+            LBMessageLength.Text = TBMessage.TextLength.ToString();
+        }
+
+        private void MainForm_Load(object sender, EventArgs e)
+        {
+
+        }
+
+        private void BTClear_Click(object sender, EventArgs e)
+        {
+            TBText.Clear();
+        }
+    }
+}

+ 120 - 0
Azylee.Utils/Tests/Test.TcpClientApp/MainForm.resx

@@ -0,0 +1,120 @@
+<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <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" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </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" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 36 - 0
Azylee.Utils/Tests/Test.TcpClientApp/Program.cs

@@ -0,0 +1,36 @@
+using Azylee.Jsons;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Test.TcpClientApp
+{
+    static class Program
+    {
+        /// <summary>
+        /// 应用程序的主入口点。
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            byte[] bt = Json.Object2Byte("测试 Json Byte 转换");
+            string __bt = Json.Byte2Object<string>(bt);
+
+            byte[] a = Encoding.UTF8.GetBytes("张无忌");
+            string __a = Encoding.UTF8.GetString(a);
+            byte[] b = Encoding.Unicode.GetBytes("张无忌");
+            string __b = Encoding.Unicode.GetString(b);
+
+            byte[] c = Encoding.UTF8.GetBytes("ぬゆまほㅙㅚЪЖ");
+            string __c = Encoding.UTF8.GetString(c);
+            byte[] d = Encoding.Unicode.GetBytes("ぬゆまほㅙㅚЪЖ");
+            string __d = Encoding.Unicode.GetString(d);
+
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new MainForm());
+        }
+    }
+}

+ 3 - 3
Azylee.Utils/Tests/Test.ProcessTool/Properties/AssemblyInfo.cs

@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
 // 有关程序集的一般信息由以下
 // 控制。更改这些特性值可修改
 // 与程序集关联的信息。
-[assembly: AssemblyTitle("Test.ProcessTool")]
+[assembly: AssemblyTitle("Test.TcpClientApp")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Test.ProcessTool")]
+[assembly: AssemblyProduct("Test.TcpClientApp")]
 [assembly: AssemblyCopyright("Copyright ©  2018")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
 [assembly: ComVisible(false)]
 
 // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("5fb93d25-8855-4a80-9e08-131bc728b7f4")]
+[assembly: Guid("b251e246-9f9c-4aec-9748-fbcfad2381e1")]
 
 // 程序集的版本信息由下列四个值组成: 
 //

+ 71 - 0
Azylee.Utils/Tests/Test.TcpClientApp/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本: 4.0.30319.42000
+//
+//     对此文件的更改可能导致不正确的行为,如果
+//     重新生成代码,则所做更改将丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Test.TcpClientApp.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("Test.TcpClientApp.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;
+            }
+        }
+    }
+}

+ 117 - 0
Azylee.Utils/Tests/Test.TcpClientApp/Properties/Resources.resx

@@ -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>

+ 30 - 0
Azylee.Utils/Tests/Test.TcpClientApp/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <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 Test.TcpClientApp.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;
+            }
+        }
+    }
+}

+ 7 - 0
Azylee.Utils/Tests/Test.TcpClientApp/Properties/Settings.settings

@@ -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>

+ 42 - 4
Azylee.Utils/Tests/Test.ProcessTool/Test.ProcessTool.csproj

@@ -4,10 +4,10 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{5FB93D25-8855-4A80-9E08-131BC728B7F4}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>Test.ProcessTool</RootNamespace>
-    <AssemblyName>Test.ProcessTool</AssemblyName>
+    <ProjectGuid>{B251E246-9F9C-4AEC-9748-FBCFAD2381E1}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>Test.TcpClientApp</RootNamespace>
+    <AssemblyName>Test.TcpClientApp</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
   </PropertyGroup>
@@ -37,17 +37,55 @@
     <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="MainForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="MainForm.Designer.cs">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </Compile>
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="MainForm.resx">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <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>
   <ItemGroup>
     <ProjectReference Include="..\..\Azylee.Core\Azylee.Core.csproj">
       <Project>{88dc61fa-95f0-41b7-9d7d-ab0f3cbd169c}</Project>
       <Name>Azylee.Core</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\Azylee.Jsons\Azylee.Jsons.csproj">
+      <Project>{de3ab999-96d3-4a53-a9f2-7409138d0333}</Project>
+      <Name>Azylee.Jsons</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Azylee.YeahWeb\Azylee.YeahWeb.csproj">
+      <Project>{ccf7a654-b442-4db1-bb3b-0f8014c3237f}</Project>
+      <Name>Azylee.YeahWeb</Name>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>

+ 210 - 0
Azylee.Utils/Tests/Test.TcpServerApp/MainForm.Designer.cs

@@ -0,0 +1,210 @@
+namespace Test.TcpServerApp
+{
+    partial class MainForm
+    {
+        /// <summary>
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows 窗体设计器生成的代码
+
+        /// <summary>
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.BTStart = new System.Windows.Forms.Button();
+            this.TBText = new System.Windows.Forms.TextBox();
+            this.TBPort = new System.Windows.Forms.TextBox();
+            this.BTStop = new System.Windows.Forms.Button();
+            this.TBType = new System.Windows.Forms.TextBox();
+            this.TBMessage = new System.Windows.Forms.TextBox();
+            this.BTSend = new System.Windows.Forms.Button();
+            this.CBHost = new System.Windows.Forms.ComboBox();
+            this.LBLine1 = new System.Windows.Forms.Label();
+            this.LBMessageLength = new System.Windows.Forms.Label();
+            this.LBTextLength = new System.Windows.Forms.Label();
+            this.LBConnect = new System.Windows.Forms.Label();
+            this.BTClear = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // BTStart
+            // 
+            this.BTStart.Location = new System.Drawing.Point(73, 10);
+            this.BTStart.Name = "BTStart";
+            this.BTStart.Size = new System.Drawing.Size(67, 23);
+            this.BTStart.TabIndex = 0;
+            this.BTStart.Text = "启动";
+            this.BTStart.UseVisualStyleBackColor = true;
+            this.BTStart.Click += new System.EventHandler(this.BTStart_Click);
+            // 
+            // TBText
+            // 
+            this.TBText.Enabled = false;
+            this.TBText.Location = new System.Drawing.Point(12, 41);
+            this.TBText.Multiline = true;
+            this.TBText.Name = "TBText";
+            this.TBText.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+            this.TBText.Size = new System.Drawing.Size(311, 200);
+            this.TBText.TabIndex = 1;
+            this.TBText.TextChanged += new System.EventHandler(this.TBText_TextChanged);
+            // 
+            // TBPort
+            // 
+            this.TBPort.Location = new System.Drawing.Point(12, 12);
+            this.TBPort.Name = "TBPort";
+            this.TBPort.Size = new System.Drawing.Size(55, 21);
+            this.TBPort.TabIndex = 2;
+            this.TBPort.Text = "52801";
+            // 
+            // BTStop
+            // 
+            this.BTStop.Location = new System.Drawing.Point(146, 10);
+            this.BTStop.Name = "BTStop";
+            this.BTStop.Size = new System.Drawing.Size(66, 23);
+            this.BTStop.TabIndex = 3;
+            this.BTStop.Text = "停止";
+            this.BTStop.UseVisualStyleBackColor = true;
+            this.BTStop.Click += new System.EventHandler(this.BTStop_Click);
+            // 
+            // TBType
+            // 
+            this.TBType.Location = new System.Drawing.Point(359, 12);
+            this.TBType.Name = "TBType";
+            this.TBType.Size = new System.Drawing.Size(53, 21);
+            this.TBType.TabIndex = 4;
+            this.TBType.Text = "1000";
+            // 
+            // TBMessage
+            // 
+            this.TBMessage.Location = new System.Drawing.Point(359, 41);
+            this.TBMessage.Multiline = true;
+            this.TBMessage.Name = "TBMessage";
+            this.TBMessage.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+            this.TBMessage.Size = new System.Drawing.Size(259, 200);
+            this.TBMessage.TabIndex = 5;
+            this.TBMessage.TextChanged += new System.EventHandler(this.TBMessage_TextChanged);
+            // 
+            // BTSend
+            // 
+            this.BTSend.Location = new System.Drawing.Point(551, 12);
+            this.BTSend.Name = "BTSend";
+            this.BTSend.Size = new System.Drawing.Size(67, 23);
+            this.BTSend.TabIndex = 6;
+            this.BTSend.Text = "发送";
+            this.BTSend.UseVisualStyleBackColor = true;
+            this.BTSend.Click += new System.EventHandler(this.BTSend_Click);
+            // 
+            // CBHost
+            // 
+            this.CBHost.FormattingEnabled = true;
+            this.CBHost.Location = new System.Drawing.Point(418, 13);
+            this.CBHost.Name = "CBHost";
+            this.CBHost.Size = new System.Drawing.Size(121, 20);
+            this.CBHost.TabIndex = 8;
+            // 
+            // LBLine1
+            // 
+            this.LBLine1.BackColor = System.Drawing.Color.Black;
+            this.LBLine1.Location = new System.Drawing.Point(340, 7);
+            this.LBLine1.Name = "LBLine1";
+            this.LBLine1.Size = new System.Drawing.Size(1, 247);
+            this.LBLine1.TabIndex = 17;
+            // 
+            // LBMessageLength
+            // 
+            this.LBMessageLength.AutoSize = true;
+            this.LBMessageLength.Location = new System.Drawing.Point(359, 244);
+            this.LBMessageLength.Name = "LBMessageLength";
+            this.LBMessageLength.Size = new System.Drawing.Size(11, 12);
+            this.LBMessageLength.TabIndex = 16;
+            this.LBMessageLength.Text = "0";
+            // 
+            // LBTextLength
+            // 
+            this.LBTextLength.AutoSize = true;
+            this.LBTextLength.Location = new System.Drawing.Point(12, 244);
+            this.LBTextLength.Name = "LBTextLength";
+            this.LBTextLength.Size = new System.Drawing.Size(11, 12);
+            this.LBTextLength.TabIndex = 15;
+            this.LBTextLength.Text = "0";
+            // 
+            // LBConnect
+            // 
+            this.LBConnect.AutoSize = true;
+            this.LBConnect.Location = new System.Drawing.Point(312, 17);
+            this.LBConnect.Name = "LBConnect";
+            this.LBConnect.Size = new System.Drawing.Size(11, 12);
+            this.LBConnect.TabIndex = 18;
+            this.LBConnect.Text = "0";
+            // 
+            // BTClear
+            // 
+            this.BTClear.Location = new System.Drawing.Point(218, 11);
+            this.BTClear.Name = "BTClear";
+            this.BTClear.Size = new System.Drawing.Size(66, 23);
+            this.BTClear.TabIndex = 19;
+            this.BTClear.Text = "清空";
+            this.BTClear.UseVisualStyleBackColor = true;
+            this.BTClear.Click += new System.EventHandler(this.BTClear_Click);
+            // 
+            // MainForm
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.BackColor = System.Drawing.SystemColors.ButtonShadow;
+            this.ClientSize = new System.Drawing.Size(626, 262);
+            this.Controls.Add(this.BTClear);
+            this.Controls.Add(this.LBConnect);
+            this.Controls.Add(this.LBLine1);
+            this.Controls.Add(this.LBMessageLength);
+            this.Controls.Add(this.LBTextLength);
+            this.Controls.Add(this.CBHost);
+            this.Controls.Add(this.BTSend);
+            this.Controls.Add(this.TBMessage);
+            this.Controls.Add(this.TBType);
+            this.Controls.Add(this.BTStop);
+            this.Controls.Add(this.TBPort);
+            this.Controls.Add(this.TBText);
+            this.Controls.Add(this.BTStart);
+            this.Name = "MainForm";
+            this.Text = "Tcp服务端";
+            this.Load += new System.EventHandler(this.Form1_Load);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Button BTStart;
+        private System.Windows.Forms.TextBox TBText;
+        private System.Windows.Forms.TextBox TBPort;
+        private System.Windows.Forms.Button BTStop;
+        private System.Windows.Forms.TextBox TBType;
+        private System.Windows.Forms.TextBox TBMessage;
+        private System.Windows.Forms.Button BTSend;
+        private System.Windows.Forms.ComboBox CBHost;
+        private System.Windows.Forms.Label LBLine1;
+        private System.Windows.Forms.Label LBMessageLength;
+        private System.Windows.Forms.Label LBTextLength;
+        private System.Windows.Forms.Label LBConnect;
+        private System.Windows.Forms.Button BTClear;
+    }
+}
+

+ 104 - 0
Azylee.Utils/Tests/Test.TcpServerApp/MainForm.cs

@@ -0,0 +1,104 @@
+using Azylee.YeahWeb.SocketUtils.TcpUtils;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Test.TcpServerApp
+{
+    public partial class MainForm : Form
+    {
+        TcppServer tcpServer = null;
+        public MainForm()
+        {
+            InitializeComponent();
+        }
+
+        private void Form1_Load(object sender, EventArgs e)
+        {
+
+        }
+
+        private void TBText_TextChanged(object sender, EventArgs e)
+        {
+            LBTextLength.Text = TBText.TextLength.ToString();
+        }
+
+        private void BTStart_Click(object sender, EventArgs e)
+        {
+            TBText.AppendText("正在监听:" + TBPort.Text + "\n");
+            tcpServer = new TcppServer(int.Parse(TBPort.Text),
+                ReceiveMessage, OnConnect, OnDisconnect);
+            tcpServer?.Start();
+        }
+
+        private void BTStop_Click(object sender, EventArgs e)
+        {
+            tcpServer?.Stop();
+            CBHost.Items.Clear();
+        }
+
+
+        private void BTSend_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                string host = CBHost.SelectedItem.ToString();
+                tcpServer.Write(host, new TcpDataModel()
+                {
+                    Type = 1000,
+                    Data = Encoding.UTF8.GetBytes(TBMessage.Text)
+                });
+            }
+            catch { }
+        }
+
+        #region Tcp 委托方法
+        private void OnConnect(string host)
+        {
+            this.Invoke(new Action(() =>
+            {
+                TBText.AppendText($"Connect : {host}" + Environment.NewLine);
+                CBHost.Items.Add(host);
+                LBConnect.Text = tcpServer.ClientsCount().ToString();
+            }));
+        }
+        private void OnDisconnect(string host)
+        {
+            this.Invoke(new Action(() =>
+            {
+                TBText.AppendText($"Disconnect : {host}" + Environment.NewLine);
+                CBHost.Items.Remove(host);
+            }));
+        }
+        private void ReceiveMessage(string host, TcpDataModel data)
+        {
+            this.Invoke(new Action(() =>
+            {
+                if (data.Type == 1000)
+                {
+                    string s = Encoding.UTF8.GetString(data.Data);
+                    int l = s.Length;
+                    TBText.AppendText(host + " : " + s);
+                    TBText.AppendText(Environment.NewLine);
+                }
+            }));
+        }
+        #endregion
+
+        private void TBMessage_TextChanged(object sender, EventArgs e)
+        {
+            LBMessageLength.Text = TBMessage.TextLength.ToString();
+        }
+
+        private void BTClear_Click(object sender, EventArgs e)
+        {
+            TBText.Clear();
+        }
+    }
+}

+ 120 - 0
Azylee.Utils/Tests/Test.TcpServerApp/MainForm.resx

@@ -0,0 +1,120 @@
+<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <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" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </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" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 22 - 0
Azylee.Utils/Tests/Test.TcpServerApp/Program.cs

@@ -0,0 +1,22 @@
+using Azylee.Core.WindowsUtils.ConsoleUtils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace Test.TcpServerApp
+{
+    static class Program
+    {
+        /// <summary>
+        /// 应用程序的主入口点。
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new MainForm());
+        }
+    }
+}

+ 4 - 4
Azylee.Utils/Azylee.Core.Plus/Properties/AssemblyInfo.cs

@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
 // 有关程序集的一般信息由以下
 // 控制。更改这些特性值可修改
 // 与程序集关联的信息。
-[assembly: AssemblyTitle("Azylee.Core.Plus")]
+[assembly: AssemblyTitle("Test.TcpServerApp")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Azylee.Core.Plus")]
+[assembly: AssemblyProduct("Test.TcpServerApp")]
 [assembly: AssemblyCopyright("Copyright ©  2018")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
 [assembly: ComVisible(false)]
 
 // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("915ae524-7efd-4ecc-b731-de1d1f5558f0")]
+[assembly: Guid("bf8291f5-3737-49ea-872b-07068d8ad4f0")]
 
 // 程序集的版本信息由下列四个值组成: 
 //
@@ -30,7 +30,7 @@ using System.Runtime.InteropServices;
 //      修订号
 //
 // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
-//通过使用 "*",如下所示:
+// 方法是按如下所示使用“*”: :
 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("1.0.0.0")]
 [assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
Azylee.Utils/Tests/Test.TcpServerApp/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本: 4.0.30319.42000
+//
+//     对此文件的更改可能导致不正确的行为,如果
+//     重新生成代码,则所做更改将丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Test.TcpServerApp.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("Test.TcpServerApp.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;
+            }
+        }
+    }
+}

+ 117 - 0
Azylee.Utils/Tests/Test.TcpServerApp/Properties/Resources.resx

@@ -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>

+ 30 - 0
Azylee.Utils/Tests/Test.TcpServerApp/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <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 Test.TcpServerApp.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;
+            }
+        }
+    }
+}

+ 7 - 0
Azylee.Utils/Tests/Test.TcpServerApp/Properties/Settings.settings

@@ -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>

+ 91 - 0
Azylee.Utils/Tests/Test.TcpServerApp/Test.TcpServerApp.csproj

@@ -0,0 +1,91 @@
+<?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>{BF8291F5-3737-49EA-872B-07068D8AD4F0}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>Test.TcpServerApp</RootNamespace>
+    <AssemblyName>Test.TcpServerApp</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </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="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="MainForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="MainForm.Designer.cs">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="MainForm.resx">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <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>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Azylee.Core\Azylee.Core.csproj">
+      <Project>{88dc61fa-95f0-41b7-9d7d-ab0f3cbd169c}</Project>
+      <Name>Azylee.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Azylee.Jsons\Azylee.Jsons.csproj">
+      <Project>{de3ab999-96d3-4a53-a9f2-7409138d0333}</Project>
+      <Name>Azylee.Jsons</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Azylee.YeahWeb\Azylee.YeahWeb.csproj">
+      <Project>{ccf7a654-b442-4db1-bb3b-0f8014c3237f}</Project>
+      <Name>Azylee.YeahWeb</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>