开发环境:VS2017

1.创建二个控制台应用,.net framework4.6.1。一个服务端,一个客户端。

2.nuget,将前五项引入二个控制台应用。

3.服务端代码:注释写代码里了

using DotNetty.Buffers;
using DotNetty.Transport.Bootstrapping;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Server
{class Program{static void Main(string[] args) => RunServerAsync().Wait();static async Task RunServerAsync(){// 主工作线程组,设置为1个线程var bossGroup = new MultithreadEventLoopGroup(1);// 工作线程组,默认为内核数*2的线程数var workerGroup = new MultithreadEventLoopGroup();try{//声明一个服务端Bootstrap,每个Netty服务端程序,都由ServerBootstrap控制,//通过链式的方式组装需要的参数var bootstrap = new ServerBootstrap();bootstrap.Group(bossGroup, workerGroup) // 设置主和工作线程组.Channel<TcpServerSocketChannel>() // 设置通道模式为TcpSocket.Option(ChannelOption.SoBacklog, 100) // 设置网络IO参数等,这里可以设置很多参数,当然你对网络调优和参数设置非常了解的话,你可以设置,或者就用默认参数吧.Option(ChannelOption.SoKeepalive, true)//保持连接.ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel =>{ //工作线程连接器 是设置了一个管道,服务端主线程所有接收到的信息都会通过这个管道一层层往下传输//同时所有出栈的消息 也要这个管道的所有处理器进行一步步处理IChannelPipeline pipeline = channel.Pipeline;//业务handler ,这里是实际处理业务的Handlerpipeline.AddLast(new HelloServerHandler());}));// bootstrap绑定到指定端口的行为 就是服务端启动服务,同样的Serverbootstrap可以bind到多个端口IChannel boundChannel = await bootstrap.BindAsync(3399);Console.WriteLine("服务启动");Console.ReadLine();//关闭服务await boundChannel.CloseAsync();}finally{//释放工作组线程await Task.WhenAll(bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)),workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));}}}public class HelloServerHandler : ChannelHandlerAdapter //管道处理基类,较常用{public override bool IsSharable => true;//标注一个channel handler可以被多个channel安全地共享。//  重写基类的方法,当消息到达时触发,这里收到消息后,在控制台输出收到的内容,并原样返回了客户端public override void ChannelRead(IChannelHandlerContext context, object message){if (message is IByteBuffer buffer){Console.WriteLine("从客户端接收: " + buffer.ToString(Encoding.UTF8));}//编码成IByteBuffer,发送至客户端string msg = "服务端从客户端接收到内容后返回,我是服务端";byte[] messageBytes = Encoding.UTF8.GetBytes(msg);IByteBuffer initialMessage = Unpooled.Buffer(messageBytes.Length);initialMessage.WriteBytes(messageBytes);context.WriteAsync(initialMessage);//写入输出流}// 输出到客户端,也可以在上面的方法中直接调用WriteAndFlushAsync方法直接输出public override void ChannelReadComplete(IChannelHandlerContext context) => context.Flush();//捕获 异常,并输出到控制台后断开链接,提示:客户端意外断开链接,也会触发public override void ExceptionCaught(IChannelHandlerContext context, Exception exception){Console.WriteLine("异常: " + exception);context.CloseAsync();}//客户端连接进来时public override void HandlerAdded(IChannelHandlerContext context){Console.WriteLine($"客户端{context}上线.");base.HandlerAdded(context);}//客户端下线断线时public override void HandlerRemoved(IChannelHandlerContext context){Console.WriteLine($"客户端{context}下线.");base.HandlerRemoved(context);}//服务器监听到客户端活动时public override void ChannelActive(IChannelHandlerContext context){Console.WriteLine($"客户端{context.Channel.RemoteAddress}在线.");base.ChannelActive(context);}//服务器监听到客户端不活动时public override void ChannelInactive(IChannelHandlerContext context){Console.WriteLine($"客户端{context.Channel.RemoteAddress}离线了.");base.ChannelInactive(context);}}
}

4.客户端代码:和服务端基本上差不多

using DotNetty.Buffers;
using DotNetty.Transport.Bootstrapping;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;namespace Client
{class Program{static void Main(string[] args) => RunClientAsync().Wait();static async Task RunClientAsync(){var group = new MultithreadEventLoopGroup();try{var bootstrap = new Bootstrap();bootstrap.Group(group).Channel<TcpSocketChannel>().Option(ChannelOption.TcpNodelay, true).Handler(new ActionChannelInitializer<ISocketChannel>(c =>{IChannelPipeline pipeline = c.Pipeline;pipeline.AddLast(new HelloClientHandler());}));IChannel clientChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3399));Console.ReadLine();await clientChannel.CloseAsync();}finally{await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));}}}class HelloClientHandler : ChannelHandlerAdapter{public override void ChannelActive(IChannelHandlerContext context){Console.WriteLine("我是客户端.");Console.WriteLine($"连接至服务端{context}.");//编码成IByteBuffer,发送至服务端string message = "客户端1";byte[] messageBytes = Encoding.UTF8.GetBytes(message);IByteBuffer initialMessage = Unpooled.Buffer(messageBytes.Length);initialMessage.WriteBytes(messageBytes);context.WriteAndFlushAsync(initialMessage);}public override void ChannelRead(IChannelHandlerContext context, object message){if (message is IByteBuffer buffer){Console.WriteLine($"IByteBuffer方式,从服务端接收:{buffer.ToString(Encoding.UTF8)}");}}public override void ChannelReadComplete(IChannelHandlerContext context) => context.Flush();public override void HandlerAdded(IChannelHandlerContext context){Console.WriteLine($"服务端{context}上线.");base.HandlerAdded(context);}public override void HandlerRemoved(IChannelHandlerContext context){Console.WriteLine($"服务端{context}下线.");base.HandlerRemoved(context);}}
}

5.运行效果:

项目下载地址:项目下载

DotNetty系列二:基本使用相关推荐

  1. 搜索引擎ElasticSearchV5.4.2系列二之ElasticSearchV5.4.2+kibanaV5.4.2+x-packV5.4.2安装

    相关博文: 搜索引擎ElasticSearchV5.4.2系列一之ES介绍 搜索引擎ElasticSearchV5.4.2系列二之ElasticSearchV5.4.2+klanaV5.4.2+x-p ...

  2. 【C++自我精讲】基础系列二 const

    [C++自我精讲]基础系列二 const 0 前言 分三部分:const用法.const和#define比较.const作用. 1 const用法 const常量:const可以用来定义常量,不可改变 ...

  3. 人工智能算法通俗讲解系列(二):逻辑回归

    2019独角兽企业重金招聘Python工程师标准>>> 今天,我们介绍的机器学习算法叫逻辑回归.它英语名称是Logistic Regression,简称LR. 跟之前一样,介绍这个算 ...

  4. 【算法系列 二】Stack

    为什么80%的码农都做不了架构师?>>>    栈应用的场景: 1.括号问题 2.后缀表达式 3.深度优先遍历 4.保存现场 1. 给定字符串,仅由"()[]{}" ...

  5. 《CDN 之我见》系列二:原理篇(缓存、安全)

    2019独角兽企业重金招聘Python工程师标准>>> <CDN之我见>共由三个篇章组成,分为原理篇.详解篇和陨坑篇.本篇章适合那些从未接触过.或仅了解一些 CDN 专业 ...

  6. SEO系列二:何为用户体验?如何做好用户体验?

    昨天写了一篇<SEO系列一:SEO是什么?SEO有什么意义?>的文章,受到了汇道童鞋们的支持和鼓舞,周珍在这里和大家说声谢谢.甚至还有童鞋说期待我写到SEO系列2000,是否能写到2000 ...

  7. 一步步构建多层架构系列二之设计模式运用篇

    上节我们讲到数据对象创建的管理,那么如何管理数据访问类的对象创建呢?先从为什么需要设计模式的原理说起吧 为了更好的理解设计思想,我尽可能的用实例来演示推进.但随着需求的增加,程序将越来越复杂.此时就有 ...

  8. 机器学习入门系列二(关键词:多变量(非)线性回归,批处理,特征缩放,正规方程

    机器学习入门系列二(关键词:多变量(非)线性回归,批处理,特征缩放,正规方程) 目录(?)[+] 一多变量的线性回归 二批处理 三特征缩放 四正规方程 五多变量非线性回归 一.多变量的线性回归 在#机 ...

  9. 图层几何学 -- iOS Core Animation 系列二

    <图层树和寄宿图 -- iOS Core Animation 系列一>介绍了图层的基础知识和一些属性方法.这篇主要内容是学习下图层在父图层上怎么控制位置和尺寸的. 1.布局 首先看一张例图 ...

最新文章

  1. 干货!解读2016-2017全球人工智能技术及产业发展的现状及趋势~
  2. “AV终结者/8749”病毒清理办法
  3. ssh架构之hibernate(一)简单使用hibernate完成CRUD
  4. 三招看穿ERP软件是否可行
  5. html邮件和纯文本邮件区别,邮件营销必读系列五--纯文本和HTML邮件类型——哪一种邮件类型更适合你?...
  6. comsol显示电场计算结果_在 COMSOL 中构建磁流体动力学多物理场模型
  7. 硬核!有人开源了一套呼吸机方案!
  8. hive 导出json格式 文件_Magicodes.IE在.NET Core中通过请求头导出多种格式文件
  9. javaweb学习总结—jsp简单标签标签库开发
  10. 基于CUDA的VTI介质有限差分正演模拟与逆时偏移及ADCIGs提取
  11. 中国物流领域首次!菜鸟路径规划算法入围全球最高工业奖项
  12. KandQ:单例模式的七种写法及其相关问题解析
  13. GitHub上最流行的10000个Java都使用了哪些库?
  14. 多个表结果的并列显示
  15. 解决xftp6 要继续使用此程序您必须应用最新的更新或使用新版本
  16. 《web安全原理分析与实践》
  17. 服务器虚拟内存可以设置其他盘,Win7系统如何把虚拟内存设置在其它盘符?
  18. 微缩脚步趋缓 摩尔定律由于EUV微影技术延迟失去动力
  19. 太湖2018年渔业产值达7.3亿元 今年大闸蟹产量将降低
  20. 数据链路层协议 ——— 以太网协议

热门文章

  1. 十部气势恢宏的经典战争片
  2. RealMedia文件格式
  3. 【MySQL】17-超详细的MySQL聚合函数总结
  4. mac系统上查看mysql数据库端口号及解决端口号为0问题
  5. 动手给自己的Blog做了个整容手术,决定在CSDN上安家了
  6. js对应css样式,JS操作CSS样式
  7. 机器学习之泰坦尼克号实战
  8. 轻松学习多线程-13-Active Object 模式
  9. 随手记——Linux中编写实时性代码时需要注意哪些问题
  10. linux命令hexdump,Linux中hexdump命令的使用