.net 平台下,实现通讯处理有很多方法(见下表),各有利弊:

序号 实现方式 特点
1 WCF 优点:封装好,方便。缺点:难学,不跨平台
2

RocketMQ,SuperSocket等中间件

优点:轻便 缺点:用户群体少
3 直接使用winsocket 优点:全部在自己掌控之下,协议灵活。缺点:实现时间长,易于出错。

本人开发socket通讯多年了,一直干着“重复发明轮子”工作,这种工作方式效率低下,容易出错!

重复的事情做多了,也会出现“灵光“!何不自己设计一套中间件,在此基础上,再设计应用层协议。就可以避免“重复发明轮子”。

先看下图,协议栈:

本文讲述的就是绿色部分如何设计。

这层协议设计原则有:

  1.  要简单 有两层意思:一是协议简单;再者使用起来简单。并且可以满足大部分应用场景。
  2. 可以跨平台  .net core本身可以跨平台。 如果对方使用c、c++开发,用其他语言实现该协议也不难。
  3. 隐藏底层细节 应用层,处理对象都是.net类,而不是字节流。
  4. 可以大数据传输  无论传输多大的数据,不必考虑分包合包处理。

设计思路

总的原则是,传输的是.net平台下的类,而不是字节流。直接处理.net类要比字节流要方便,安全很多。

.net平台下类型很多,我提取了最常用的几种,达到即简单,又满足大部分应用场景的要求。

可以传输的类型有:int、string、short、long,byte;

以及对应链表类型: List<int>、List<string>、List<short>、List<long>、byte[];

协议总的包体:

public class NetPacket
{
public int PacketType { get; set; } // 包类型
public int Param1 { get; set; } // 参数1 ,可以根据实际情况使用
public int Param2 { get; set; } // 参数2 ,可以根据实际情况使用
        public List<NetValuePair> Items { get; set; } //传输的key value 列表
}
NetValuePair 定义如下:
    public class NetValuePair
{
public string Key { get; set; }
public NetValueBase Value { get; set; } public NetValuePair()
{ }
}

 NetValueBase 包含子类型,分别对应string、int等。以string类型举例:

public class NetValueBase
{
public EN_DataType ValueType { get;protected set; } public virtual object GetValue()
{
return null;
}
}

  

public class NetValueString: NetValueBase
{
public string Value { get; set; } = string.Empty;
public override object GetValue()
{
return Value;
} public NetValueString()
{
ValueType = EN_DataType.en_string;
} public NetValueString(string value)
{
ValueType = EN_DataType.en_string;
Value = value;
}
}
NetValueString值最终要以字节流方式传送出去,采用如下方式序列化:
string值采用utf8传输,先将字符串转换成字节流;分别写入字节流的长度,实际的字节流;
在序列化中,没用多余字段。比.net 自带的序列化类处理要高效的多,大家可以对比下。
 internal static void WriteStringValue(Stream stream, string value)
{
byte[] bytes = Encoding.UTF8.GetBytes(value); WriteInt32(stream, bytes.Length);
stream.Write(bytes, 0, bytes.Length);
}

其它类型的序列化,与此类似,不在累述。反序列化如何操作,也不难想像。

传输

序列化后的数据要发送出去,需要下一层来处理。

这层的主要功能就是分包和合包。(数据很小的时候就不需要分包了)

public class RawNetPacket
{
public static int HeadLen = 14;
public UInt16 PacketLen;
public UInt32 PacketId; //一个完整的包 唯一id
public UInt32 TotalNO; //共有多少个包
public UInt32 PacketNO; //包序列号
public byte[] Body; //承载NetPacket序列化的数据,有可能分包发送
}  

具体如何分包和合包,可以参考附件源码。

使用举例

1 传送文件

 private NetPacket GetPacketByFile(string fileName)
{
using (FileStream stream = new FileInfo(fileName).OpenRead())
{
NetPacket result = new NetPacket();
result.PacketType = 2;
result.Param1 = 2;
result.Param2 = 3;
result.Items = new List<NetValuePair>(); //string
NetValuePair pair = new NetValuePair();
pair.Key = "文件名称";
pair.Value = new NetValueString(fileName);
result.Items.Add(pair); //byte
pair = new NetValuePair();
pair.Key = "文件二进制数据";
NetValueListByte fileBuffer = new NetValueListByte();
fileBuffer.Value = new byte[stream.Length];
stream.Read(fileBuffer.Value, 0, Convert.ToInt32(stream.Length)); pair.Value = fileBuffer;
result.Items.Add(pair);
return result;
}
}

 2 传输对象

可以将对象序列化为json字符串,再传送。

.net 平台下, Socket通讯协议中间件设计思路(附源码)的更多相关文章

  1. YYCache设计思路及源码学习

    设计思路 利用YYCache来进行操作,实质操作分为了内存缓存操作(YYMemoryCache)和硬盘缓存操作(YYDiskCache).内存缓存设计一般是在内存中开辟一个空间用以保存请求的数据(一般 ...

  2. 可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)

      (最新版本:V6.2,2019.01.03 .Xamarin移动端版本已经推出,包括 Android 和 iOS) GGTalk开源即时通讯系统(简称GG)是QQ的高仿版,同时支持局域网和广域网, ...

  3. 【转】可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)

    原文地址:http://www.cnblogs.com/justnow/p/3382160.html (最新版本:V6.0,2017.12.11 .即将推出Xamarin移动端版本,包括 Androi ...

  4. asp.net abp模块化开发之通用树2:设计思路及源码解析

    一.前言 上一篇大概说了下abp通用树形模块如何使用,本篇主要分析下设计思路. 日常开发中会用到很多树状结构的数据,比如:产品的多级分类.省市区县,大多数系统也会用到类似“通用字典/数据字典”的功能, ...

  5. 分享基于Entity Framework的Repository模式设计(附源码)

    关于Repository模式,在这篇文章中有介绍,Entity Framework返回IEnumerable还是IQueryable? 这篇文章介绍的是使用Entity Framework实现的Rep ...

  6. CopyOnWriteArrayList设计思路与源码分析

    CopyOnWriteArrayList实现了List接口,RandomAccess,Cloneable,Serializable接口. CopyOnWriteArrayList特性 1.线程安全,在 ...

  7. .net平台下socket异步通讯(代码实例)

    你应该知道的.net平台下socket异步通讯(代码实例) 1,首先添加两个windows窗体项目,一个作为服务端server,一个作为客户端Client 2,然后添加服务端代码,添加命名空间,界面上 ...

  8. Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析

    Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析 生鲜电商搜索引擎的特点 众所周知,标准的搜索引擎主要分成三个大的部分,第一步是爬虫系统,第二步是数据分析,第三步才 ...

  9. 轻量级通信引擎StriveEngine —— C/S通信demo(2) —— 使用二进制协议 (附源码)

    在网络上,交互的双方基于TCP或UDP进行通信,通信协议的格式通常分为两类:文本消息.二进制消息. 文本协议相对简单,通常使用一个特殊的标记符作为一个消息的结束. 二进制协议,通常是由消息头(Head ...

随机推荐

  1. 自学Zabbix3.9.1-模板Templates-创建

    自学Zabbix3.9.1-模板Templates-创建 1. 模板介绍 模板是一组可以方便地应用于多个主机的实体. 实体可能是: 项目 触发器 图 应用程序 屏幕(因为Zabbix 2.0) 低层次 ...

  2. linux系统下安装单台Redis

    注意:搭建redis前一定要安装gcc redis安装方式一 1.安装gcc命令:yum install -y gcc #安装gcc [root@localhost src]# yum install ...

  3. python每天进步一点点

    1. apply, 可以调用函数和参数,如apply(Fun,(xxx,xxx)) 2. Format, 很好处理字符串的对齐命名,其他进制,打印等. 3. input(),接受输入 4. str() ...

  4. 【CSS3】表格、列表

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. HTML基础教程-元素

    HTML 元素 HTML 文档是由 HTML 元素定义的. HTML 元素 HTML 元素指的是从开始标签(start tag)到结束标签(end tag)的所有代码. 注释:开始标签常被称为开放标签 ...

  6. JS画几何图形之二【圆】

    半径为r的圆上的点p(x,y)与圆心O(x0,y0)的关系: x = x0+rcosA;  y = y0+rsinA ,A为弧度 样例:http://www.zhaojz.com.cn/demo/dr ...

  7. ES6 Proxy和Reflect (上)

    Proxy概述 Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种"元编程"(meta programming),即对编程语言进行编程. Proxy可以理 ...

  8. Windows 刷新DNS缓存

    释放IP配置信息 ipconfig /release 刷新DNS ipconfig /flushdns 更新网卡适配器 ipconfig /renew

  9. MobaXterm

    MobaXterm又名MobaXVT,是一款增强型终端.X服务器和Unix命令集(GNU/ Cygwin)封装在一个单一的便携式exe文件.MobaXterm可以开启多个终端视窗,以最新的X服务器为基 ...

  10. Mysql使用alias 防止对数据的误操作

    在我们操作数据库的时候,尤其是执行,update,delete操作的时候,都存在着误操作的风险,今天发现一种方法,能避免这一问题,就是使用Mysql的alias . 1.查看Mysql帮助 #mysq ...