一、Netty初步

为什么选择Netty?

和NIO比较,要实现一个通信要简单得很多,性能很好。分布式消息中间件、storm、Dubble都是使用Netty作为底层通信。

Netty5.0要求jdk1.6以上。

http://netty.io

二、编码步骤

创建两个Nio线程组,一个事件处理,一个网络读写通信

创建一个ServerBootStrap,配置Netty参数;

创建实际处理的ChannelInitializer,进行初始化的准备工作,比如设置接收传出的字符集,格式,已经实际处理数据接口

绑定端口执行同步阻塞方法等待服务器端启动。

并发编程网 http://ifeve.com/netty5-user-guide

三、代码

服务端

  1. import io.netty.bootstrap.ServerBootstrap;
  2. import io.netty.channel.ChannelFuture;
  3. import io.netty.channel.ChannelInitializer;
  4. import io.netty.channel.ChannelOption;
  5. import io.netty.channel.EventLoopGroup;
  6. import io.netty.channel.nio.NioEventLoopGroup;
  7. import io.netty.channel.socket.SocketChannel;
  8. import io.netty.channel.socket.nio.NioServerSocketChannel;
  9.  
  10. /**
  11. * Created by sgm on 2017/1/28.
  12. */
  13. public class Server {
  14. public static void main(String []args) throws InterruptedException {
  15. /**
  16. * EventLoopGroup 事件组,不同的事件组处理不同的协议,这里使用NioEventLoopGroup来处理Tcp协议
  17. * 第一个事件循环组用来接收客户端信息,通常被称作boss,boos接收到信息后注册到worker上
  18. * 第二个事件循环组做实际的业务处理
  19. */
  20. EventLoopGroup bossGroup = new NioEventLoopGroup();
  21. EventLoopGroup workerGroup = new NioEventLoopGroup();
  22.  
  23. /**
  24. * 引导,对server进行一系列的配置
  25. */
  26. ServerBootstrap b = new ServerBootstrap();
  27. //将boss和worker关联起来
  28. b.group(bossGroup,workerGroup)
  29. .channel(NioServerSocketChannel.class)//使用的通道类型
  30. .childHandler(new ChannelInitializer<SocketChannel>() {
  31. @Override
  32. protected void initChannel(SocketChannel socketChannel) throws Exception {
  33. socketChannel.pipeline().addLast(new ServerHandler());
  34. }
  35. })//添加serverHandler,绑定具体的事件处理器
  36. /**
  37. * 当客户端向客户端发送请求会带一个信号,服务器端返回一个信号并且将客户端的链接信息加入队列A中,
  38. * 服务器再收到一个客户端的信号并且将客户端的信息从队列A移动到队列B中;
  39. * 队列A和队列B的长度之和就是BACKLOG,如果大于了BACKLOG,tcp内核就会拒绝链接,BACKLOG只会影响到没有被accept取出的链接
  40. */
  41. .option(ChannelOption.SO_BACKLOG,128)
  42. .option(ChannelOption.SO_KEEPALIVE,true);//保持连接
  43. ChannelFuture cf = b.bind(9876).sync();//绑定端口进行监听,异步的监听
  44.  
  45. cf.channel().closeFuture().sync();//阻塞
  46. workerGroup.shutdownGracefully();
  47. bossGroup.shutdownGracefully();
  48.  
  49. }
  50. }
  1. import io.netty.buffer.ByteBuf;
  2. import io.netty.buffer.Unpooled;
  3. import io.netty.channel.ChannelHandlerAdapter;
  4. import io.netty.channel.ChannelHandlerContext;
  5. import io.netty.util.ReferenceCountUtil;
  6.  
  7. /**
  8. * Created by Administrator on 2017/1/28.
  9. */
  10. public class ServerHandler extends ChannelHandlerAdapter{
  11.  
  12. @Override
  13. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  14. try {
  15. //do something msg
  16. ByteBuf buf = (ByteBuf)msg;
  17. byte[] data = new byte[buf.readableBytes()];
  18. buf.readBytes(data);
  19. String request = new String(data, "utf-8");
  20. System.out.println("Server: " + request);
  21. //写给客户端
  22. String response = "我是反馈的信息";
  23. ctx.writeAndFlush(Unpooled.copiedBuffer("888".getBytes()));
  24. }finally {
  25. ReferenceCountUtil.release(msg);//有上一句话,即ctx.writeAndFlush(),这里可以不关闭
  26. }
  27. }
  28.  
  29. @Override
  30. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  31. cause.printStackTrace();
  32. ctx.close();
  33. }
  34. }

客户端

  1. import io.netty.bootstrap.Bootstrap;
  2. import io.netty.buffer.Unpooled;
  3. import io.netty.channel.ChannelFuture;
  4. import io.netty.channel.ChannelInitializer;
  5. import io.netty.channel.EventLoopGroup;
  6. import io.netty.channel.nio.NioEventLoopGroup;
  7. import io.netty.channel.socket.SocketChannel;
  8. import io.netty.channel.socket.nio.NioSocketChannel;
  9.  
  10. public class Client {
  11.  
  12. public static void main(String[] args) throws Exception {
  13.  
  14. EventLoopGroup workgroup = new NioEventLoopGroup();
  15. Bootstrap b = new Bootstrap();
  16. b.group(workgroup)
  17. .channel(NioSocketChannel.class)
  18. .handler(new ChannelInitializer<SocketChannel>() {
  19. @Override
  20. protected void initChannel(SocketChannel sc) throws Exception {
  21. sc.pipeline().addLast(new ClientHandler());
  22. }
  23. });
  24.  
  25. ChannelFuture cf1 = b.connect("127.0.0.1", 9876).sync();
  26.  
  27. //buf
  28. cf1.channel().writeAndFlush(Unpooled.copiedBuffer("777".getBytes()));
  29.  
  30. cf1.channel().closeFuture().sync();
  31. workgroup.shutdownGracefully();
  32.  
  33. }
  34. }
  1. import io.netty.buffer.ByteBuf;
  2. import io.netty.buffer.Unpooled;
  3. import io.netty.channel.ChannelHandlerAdapter;
  4. import io.netty.channel.ChannelHandlerContext;
  5. import io.netty.util.ReferenceCountUtil;
  6.  
  7. public class ClientHandler extends ChannelHandlerAdapter {
  8.  
  9. @Override
  10. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  11. try {
  12. //do something msg
  13. ByteBuf buf = (ByteBuf)msg;
  14. byte[] data = new byte[buf.readableBytes()];
  15. buf.readBytes(data);
  16. String request = new String(data, "utf-8");
  17. System.out.println("Client: " + request);
  18.  
  19. } finally {
  20. ReferenceCountUtil.release(msg);
  21. }
  22. }
  23.  
  24. @Override
  25. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  26. cause.printStackTrace();
  27. ctx.close();
  28. }
  29. }

架构师养成记--19.netty的更多相关文章

  1. 架构师养成记--21.netty编码解码

    背景 作为网络传输框架,免不了哟啊传输对象,对象在传输之前就要序列化,这个序列化的过程就是编码过程.接收到编码后的数据就需要解码,还原传输的数据. 代码 工厂类 import io.netty.han ...

  2. 架构师养成记--20.netty的tcp拆包粘包问题

    问题描述 比如要发ABC DEFG HIJK 这一串数据,其中ABC是一个包,DEFG是一个包,HIJK是一个包.由于TCP是基于流发送的,所以有可能出现ABCD EFGH 这种情况,那么ABC和D就 ...

  3. 架构师养成记--22.客户端与服务器端保持连接的解决方案,netty的ReadTimeoutHandler

    概述 保持客户端与服务器端连接的方案常用的有3种 1.长连接,也就是客户端与服务器端一直保持连接,适用于客户端比较少的情况. 2.定时段连接,比如在某一天的凌晨建立连接,适用于对实时性要求不高的情况. ...

  4. 架构师养成记--35.redis集群搭建

    前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...

  5. 架构师养成记--15.Disruptor并发框架

    一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...

  6. 架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock

    ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决 ...

  7. 架构师养成记--12.Concurrent工具类CyclicBarrier和CountDownLatch

    java.util.concurrent.CyclicBarrier 一组线程共同等待,直到达到一个公共屏障点. 举个栗子,百米赛跑中,所有运动员都要等其他运动员都准备好后才能一起跑(假如没有发令员) ...

  8. 架构师养成记--11.Executor概述

    常用方法 Executors.newFiexdPool(int nThreads);固定线程数量的线程池: Executors.newSingleThreadExecutor();单个线程的线程池: ...

  9. 架构师养成记--10.master-worker模式

    master-worker模式是一种并行计算模式,分为master进程和worker进程两个部分,master是担任总管角色,worker才是执行具体任务的地方. 总体流程应该是这样的: 具体一点,代 ...

随机推荐

  1. Multiply Strings大整数乘法

    [抄题]: 以字符串的形式给定两个非负整数 num1 和 num2,返回 num1 和 num2 的乘积. [暴力解法]: 时间分析: 空间分析: [思维问题]: 还要找到结果中第一位不等于0的数再添 ...

  2. cmake条件编译

    CMake的条件编译基于if elseif endif.3.0版本具体语法如下 if(expression) # then section. COMMAND1(ARGS ...) COMMAND2(A ...

  3. vbs执行系统命令

    首先说明一下,我的所有代码都是vbscript,jscript我没有研究过,不过我想也差不多. 关于最基础的语法比如变量的申明,分支,循环,函数的调用,等等这些我就不讲了,不懂得自己看一下. 1.我们 ...

  4. Mybatis之是如何执行你的SQL的(SQL执行过程,参数解析过程,结果集封装过程)

    Myabtis的SQL的执行是通过SqlSession.默认的实现类是DefalutSqlSession.通过源码可以发现,selectOne最终会调用selectList这个方法. @Overrid ...

  5. C++笔记16之const的用法总结

    const主要是为了程序的健壮型,减少程序出错. 最基本的用法: const int a=100; b的内容不变,b只能是100也就是声明一个int类型的常量(#define b =100) int  ...

  6. 作业3:PSP记录耗时情况

    PSP2.1 Personal Software Process Stage Time planning 计划 10min Estimate 估计这个任务多久完成 150min Developing ...

  7. 如何注册GitHub

    一.个人介绍 姓名:张志龙 学号:1413042026 班级:网工141 爱好:宅物 能力:c++编程 二.注册 注册GitHub其实很简单 首先我们要做的是打开官网 www.github.com(如 ...

  8. vue实现首页导航切换不同路由的方式(二)【使用vuex实现的】

    <nav> <!-- 导航栏 --> <div class="indexNavOut"> <div class="indexNa ...

  9. python signal

    在了解了Linux的信号基础之 后,Python标准库中的signal包就很容易学习和理解.signal包负责在Python程序内部处理信号,典型的操作包括预设信号处理函数,暂 停并等待信号,以及定时 ...

  10. 10-09 Linux的文件系统介绍以及各种设备的说明

    Linux的文件编程 linux文件管理系统分为3部分:与文件管理有关的软件,被管理的文件,实施文件管理需要的数据结构 用C语言建立,打开,关闭文件,向文件写入和读出数据等. Linux文件系统简介 ...