.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. js实现刷新

    Javascript刷新页面的几种方法: 代码如下:1,history.go(0) 2,location.reload() 3,location=location 4,location.assign( ...

  2. 总结一下现在关于Design Support Library的几个博客

    原文转载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0713/3179.html 关于Design Support Libr ...

  3. Xcode中StoryBoard Reference 新特性的使用

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  4. 【TEGer 在全球架构师峰会】 : 腾讯海外计费系统架构演进

    欢迎大家前往云加社区,获取更多腾讯海量技术实践干货哦~ 作者简介:abllen,2008年加入腾讯,一直专注于腾讯计费平台建设,主导参与了腾讯充值中心.计费开放平台.统一计费米大师等项目,见证了米大师 ...

  5. gearman学习笔记1

    1.简介       gearman是一个分布式开发框架,适合处理一些必须处理但是不影响主流程的操作,比如保存日志.发送邮件.缩略图片等.最早是基于perl语言的,2008年发布的时候改为C++语言开 ...

  6. sourceTree每次拉取代码和提交代码都需要输入密码

    今天新安装的sourceTree导入项目,拉取代码的时候一直提示让我输入git密码,每次拉取和提交的时候都需要重新输入密码,甚是麻烦,在网上,搜索,解决办法五花八门,这里提供一种简单有效的方法供大家参 ...

  7. arcgis api for js之echarts开源js库实现地图统计图分析

    前面写过一篇关于arcgis api for js实现地图统计图的,具体见:http://www.cnblogs.com/giserhome/p/6727593.html 那是基于dojo组件来实现图 ...

  8. ArcGIS 网络分析[2.1] 最短路径

    最短路径求解 [如果看到此博客还没有网络数据集的,请参考第一章的内容,点击我,看目录] 最短路径,是什么最短?时间最短?距离最短?什么距离?路程距离? 考虑到拥堵问题,限速问题,换乘问题,在现实的最短 ...

  9. .net 连接SqlServer数据库及基本增删改查

    一.写在前面 因为这学期选修的 .net 课程就要上机考试了,所以总结下.net 操作 SqlServer 数据的方法.(因为本人方向是 Java,所以对.net 的了解不多,但以下所写代码均是经过测 ...

  10. 1.Nginx服务应用

    Nginx服务应用 Nginx的优点和作用 Nginx是一款高性能的HTTP和反向代理的服务器软件,还是一个IMAP/POP3/SMTP(邮件)代理服务器! Nginx在功能实现上都采用模块化结构设计 ...