美文网首页
一个简单 小型的C#Socket网络通信库的制作(服务器客户端互

一个简单 小型的C#Socket网络通信库的制作(服务器客户端互

作者: 懒_开果 | 来源:发表于2019-07-29 16:23 被阅读0次
就一个不用 理解之间的通信代码原理之类的 几句代码快速搭建服务器和客户端

思维导图:

image.png

过程大概是KGSocketClient/KGSocketServe 创建了KGNetSession 会话管理进行发送/接收数据的监听会进行一次开启事件 OnStartRecive() 函数回调, 监听到的数据包KGNetPacket 通过KGPackExtension 转化成KGNetData自已定义的数据结构类,然后在KGNetSession里面的 OnReciveData(T) 函数 进行回调

下面直接开始代码解析

1.KGNetData 自定义的数据类

这个好像没啥好说的=。= 自定义的数据类都要继承他



//传输的数据都必须打上可序列化的标签
[Serializable]
  public abstract class KGNetData
    {
        public int Err;
        public int Cmd;
    }


2.KGNetPacket 消息包的数据类

[图片上传失败...(image-3c0ba8-1564388496437)]

因为每条消息包 你不知道他的长度 所以要在前面利用BitConverter.GetBytes获取一个包的长度Int值

这个int就站byte[]四个长度 所以HeadLength=4,然后获取到长度了在SetPackLen给PacketBuff赋值上获取到的长度

 public class KGNetPacket
    {


        public byte[] PacketBuff;


        public int HeadLength = 4;//这里是标头的长度
        public int HeadIndex;//这里有时候分包接收到一两个 所以要进行记录已经接收到两个了 还差几个

        public int PacketBuffLength ;//数据包的长度
        public int PacketIndex;//和上面一样意思

        /// <summary>
        /// 获取四个字节转成的int长度
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public  void SetPackLen()
        {
            PacketBuffLength = BitConverter.ToInt32(PacketBuff, 0);
            PacketBuff =new byte[PacketBuffLength];
        }


        public void Refresh()
        {
            PacketBuff = null;
            PacketIndex = 0;
            HeadIndex = 0;
        }
    }

3.KGPackExtension 打消息包拓展工具类

    /// <summary>
    /// 打包消息的拓展工具类
    /// </summary>
    public static class KGPackExtension
    {
        


 #region 打包消息包的

        /// <summary>
        /// 反序列化消息包返回自定义数据类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static T DeSerialization<T>(this byte[] data) where T:KGNetData
        {
            //using 创建完会自动释放内存 创建流MemoryStream 读消息
            using (MemoryStream ms=new MemoryStream(data))
            {
                //BinaryFormatter 用来反,序列化流的
                BinaryFormatter binary = new BinaryFormatter();
                //反序列成自定义数据类型
                T netdata =  (T) binary.Deserialize(ms);
                return netdata;
            }
        }

        /// <summary>
        /// 把自定义数据类型序列化成byte[] 数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        private static byte[] Serialization<T>(this T data) where T : KGNetData
        {
            //using 创建完会自动释放内存 创建流MemoryStream 
            using (MemoryStream ms = new MemoryStream())
            {
                //BinaryFormatter 用来反,序列化流的
                BinaryFormatter binary = new BinaryFormatter();
                //把数据写进去流里面
               binary.Serialize(ms,data);
               //这里是指定流开始的位置
                ms.Seek(0, SeekOrigin.Begin);
                //转换byte[]返回
                return ms.ToArray();
            }
        }

        /// <summary>
        /// 为消息包前头增加消息包长度
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] PackNetDataLen(this byte[] data)
        {
            //获取消息包长度返回一个byte[4]          //连接合并数据包   进行最终返回
            return BitConverter.GetBytes(data.Length).Concat(data).ToArray();
        }

     
        /// <summary>
        /// 打包自定义数据类的消息包 加上包长
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] PackNetData<T>(this T data) where T : KGNetData
        {
            return data.Serialization().PackNetDataLen();
        }
#endregion
    }

4.KGLog 打印消息的 工具类

所有打印都是通过KLog()进行打印的 在别的地方可以在LogEvent就可以获取到打印事件了

    /// <summary>
    /// 打印消息的工具拓展类
    /// </summary>
    public static class KGLog
    {
        public static bool RunLog = true;

        //留的一个打印事件委托
        private static  Action<string, LogLevel> LogEvent = null;

        //这里是打印消息的方法
        public static void KLog(this string Logdata,LogLevel logLevel=LogLevel.Common)
        {
            if (!RunLog)
                return;

            LogEvent?.Invoke(Logdata,logLevel);

            Console.WriteLine("{0}-----------------{1}", Logdata,logLevel.ToString());
         

        }

        public static void SetLog(this Action<string, LogLevel> log,bool Run=true)
        {
            LogEvent = log;
            RunLog = Run;
        }
    }

    //打印等级
    public enum  LogLevel
    {
        None=0,
        Common=1,
        Warn=2,
        Err=3

    }

好了 差不多结束了=。= 不定期更新下篇

u3d萌新QQ群844087555——一个除了unity3d啥都会的群

相关文章

网友评论

      本文标题:一个简单 小型的C#Socket网络通信库的制作(服务器客户端互

      本文链接:https://www.haomeiwen.com/subject/dcobrctx.html