package com.example.demohystrix.process;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.string.StringEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.nio.charset.Charset; /**
* @author liusongwei
* @Title: NettyServer
* @ProjectName claimfront
* @Description: TODO
* @date 2019/3/2216:26
*/
public class NettyServer {
private static Logger log = LoggerFactory.getLogger(NettyServer.class); private final int port; public NettyServer(int port) {
this.port = port;
} public void start() throws Exception {
//用来接收进来的连接
EventLoopGroup bossGroup = new NioEventLoopGroup(); //用来处理已经被接收的连接
EventLoopGroup group = new NioEventLoopGroup();
try {
//启动 NIO 服务的辅助启动类
ServerBootstrap sb = new ServerBootstrap();
sb.option(ChannelOption.SO_BACKLOG, );//设置TCP缓冲区
// sb.option(ChannelOption.SO_SNDBUF,32*1024);//设置发送缓冲大小
// sb.option(ChannelOption.SO_RCVBUF,32*1024);//设置接收缓冲大小
// sb.option(ChannelOption.SO_KEEPALIVE,true);//保持连接
sb.group(group, bossGroup) // 绑定两个线程组
.channel(NioServerSocketChannel.class) // 指定NIO模式
.localAddress(this.port)// 绑定监听端口
// 绑定客户端连接时候触发操作 添加一个EchoServerHandler到子Channel的ChannelPipeline
//ChannelInitializer 当一个新的连接被接收时,一个新的子Channel将会被创建
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
log.info("客户端连接,连接的IP:{}",ch.localAddress().getHostName());
ch.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
//EchoServerHandler被标注为@Shareable,所以我们可以总是使用同样的实例
ch.pipeline().addLast(new NettyServerHandler()); // 客户端触发操作
ch.pipeline().addLast(new ByteArrayEncoder());
}
});
//异步绑定服务器,调用sync()方法阻塞等待直到绑定完成
ChannelFuture cf = sb.bind().sync(); //获取Channel的closeFuture,并且阻塞当前线程直到它完成
cf.channel().closeFuture().sync();
log.info(" 启动正在监听:{}",cf.channel().localAddress());
} finally {
group.shutdownGracefully().sync(); // 释放线程池资源
bossGroup.shutdownGracefully().sync();
}
} public static void main(String[] args) throws Exception { new NettyServer().start(); // 启动
}
}
package com.example.demohystrix.process;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.UnsupportedEncodingException; /**
* @author liusongwei
* @Title: NettyServerHandler
* @ProjectName claimfront
* @Description: TODO
* @date 2019/3/2216:31
*/
//标示一个ChannelHandler可以被多个Channel安全地共享
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
private static Logger log = LoggerFactory.getLogger(NettyServerHandler.class);
/*
* channel 通道 action 活跃的 回调调用
* 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
*/
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println(ctx.channel().localAddress().toString() + " 通道已激活!");
} /*
* channelInactive
*
* channel 通道 Inactive 不活跃的
*
* 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
*
*/
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println(ctx.channel().localAddress().toString() + " 通道不活跃!");
// 关闭流
} /**
* TODO 此处用来处理收到的数据中含有中文的时 出现乱码的问题
*/
private String getMessage(ByteBuf buf) {
byte[] con = new byte[buf.readableBytes()];
buf.readBytes(con);
try {
return new String(con, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
} /**
* 功能:读取服务器发送过来的信息
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// 第一种:接收字符串时的处理
ByteBuf buf = (ByteBuf) msg;
String rev = getMessage(buf);
log.info("服务端收到的数据:" + rev);
//将接收到的消息写给发送者,而不冲刷出站消息
ctx.write("消息已接收");
} /**
* 功能:读取完毕客户端发送过来的数据之后的操作
*/
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
System.out.println("服务端接收数据完毕..");
// 第一种方法:写一个空的buf,并刷新写出区域。完成后关闭sock channel连接。
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
// ctx.flush();
// ctx.flush(); //
// 第二种方法:在client端关闭channel连接,这样的话,会触发两次channelReadComplete方法。
// ctx.flush().close().sync(); // 第三种:改成这种写法也可以,但是这中写法,没有第一种方法的好。
} /**
* 功能:服务端发生异常的操作
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
System.out.println("异常信息:\r\n" + cause.getMessage());
}
}
package com.example.demohystrix.process;

import java.net.InetSocketAddress;
import java.nio.charset.Charset; import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* @author liusongwei
* @Title: NettyClient
* @ProjectName algorithmrsa
* @Description: TODO
* @date 2019/3/2216:37
*/
public class NettyClient {
private static Logger log = LoggerFactory.getLogger(NettyServer.class); private final String host;
private final int port; public NettyClient() {
this();
} public NettyClient(int port) {
this("localhost", port);
} public NettyClient(String host, int port) {
this.host = host;
this.port = port;
} public void start() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group) // 注册线程池
.channel(NioSocketChannel.class) // 使用NioSocketChannel来作为连接用的channel类
.remoteAddress(new InetSocketAddress(this.host, this.port)) // 绑定连接端口和host信息
.handler(new ChannelInitializer<SocketChannel>() { // 绑定连接初始化器
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//ch.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
ch.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
ch.pipeline().addLast(new NettyClientHandler());
ch.pipeline().addLast(new ByteArrayEncoder());
ch.pipeline().addLast(new ChunkedWriteHandler()); }
});
ChannelFuture cf = b.connect().sync(); // 异步连接服务器
log.info("服务端连接成功...");
cf.channel().closeFuture().sync(); // 异步等待关闭连接channel
log.info("连接已关闭...");
} finally {
group.shutdownGracefully().sync(); // 释放线程池资源
}
} public static void main(String[] args) throws Exception {
new NettyClient("127.0.0.1", ).start(); // 连接127.0.0.1/65535,并启动
// new NettyClient("127.0.0.1", 8888).start(); // 连接127.0.0.1/65535,并启动 }
}
package com.example.demohystrix.process;

import java.nio.charset.Charset;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* @author liusongwei
* @Title: NettyClientHandler
* @ProjectName algorithmrsa
* @Description: TODO
* @date 2019/3/2216:40
*/
public class NettyClientHandler extends SimpleChannelInboundHandler<ByteBuf>{
private static Logger log = LoggerFactory.getLogger(NettyServer.class);
/**
* 向服务端发送数据
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
log.info("客户端与服务端通道-开启:" + ctx.channel().localAddress() + "channelActive");
String sendInfo = "Hello 这里是客户端 你好啊!";
ctx.writeAndFlush(Unpooled.copiedBuffer(sendInfo, CharsetUtil.UTF_8)); // 必须有flush
} /**
* 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
*/
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
log.info("客户端与服务端通道-关闭:" + ctx.channel().localAddress() + "channelInactive");
} @Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
System.out.println("读取客户端通道信息..");
ByteBuf buf = msg.readBytes(msg.readableBytes());
//log.info("收到信息:"+ByteBufUtil.hexDump(buf) + "; 数据包为:" + buf.toString(Charset.forName("utf-8")));
log.info("收到信息:"+ByteBufUtil.hexDump(buf) + "; 数据包为:" + buf.toString(Charset.forName("GBK")));
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
log.info("异常退出:" + cause.getMessage());
}
}

netty简单样例的更多相关文章

  1. extern外部方法使用C#简单样例

    外部方法使用C#简单样例 1.添加引用using System.Runtime.InteropServices; 2.声明和实现的连接[DllImport("kernel32", ...

  2. spring事务详解(二)简单样例

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...

  3. velocity简单样例

    velocity简单样例整体实现须要三个步骤,详细例如以下: 1.创建一个Javaproject 2.导入须要的jar包 3.创建须要的文件 ============================= ...

  4. 自己定义隐式转换和显式转换c#简单样例

    自己定义隐式转换和显式转换c#简单样例 (出自朱朱家园http://blog.csdn.net/zhgl7688) 样例:对用户user中,usernamefirst name和last name进行 ...

  5. VC6 鼠标钩子 最简单样例

    Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它能够截获并处理送给其它应用程序的消息,来完毕普通应用程序 ...

  6. gtk+3.0的环境配置及基于gtk+3.0的python简单样例

    /*********************************************************************  * Author  : Samson  * Date   ...

  7. java 使用tess4j实现OCR的最简单样例

    网上很多教程没有介绍清楚tessdata的位置,以及怎么配置,并且对中文库的描述也存在问题,这里介绍一个最简单的样例. 1.使用maven,直接引入依赖,确保你的工程JDK是1.8以上 <dep ...

  8. 使用SALT-API进入集成开发的简单样例

    测试的时候,可以CURL -K,但真正作集成的时候,却是不可以的. 必须,不可以让TOKEN满天飞吧. 现在进入这个阶段了.写个样例先: import salt import salt.auth im ...

  9. VB.net数据库编程(03):一个SQLserver连接查询的简单样例

    这个样例,因为在ADO.net入门已经专门学了,再次进行复习 一下. 主要掌握连接字串的情况. 过程就是: 1.引用System.Data.SqlClient.而Access中引用 的是System. ...

随机推荐

  1. jQuery 对AMD的支持(Require.js中如何使用jQuery)

    AMD 模块 AMD(异步模块定义,Asynchronous Module Definition)格式总体的目标是为现在的开发者提供一个可用的模块化 JavaScript 的解决方案. AMD 模块格 ...

  2. 个人练习:使用HTML+CSS制作二级菜单

    最近一直在学习HTML+CSS,刚看完如果制作下拉菜单部分,就想着做一个练练手. 先上成品图: 就是上面这个效果,横向菜单选项能点击,鼠标放在上面也能展开二级菜单,二级菜单也能点击,点击后就会在底下的 ...

  3. SAP WM 有无保存WM Level历史库存的Table?

    SAP WM 有无保存WM Level历史库存的Table? 前日下班回家的路上,收到一个前客户内部顾问同行发过来的微信,问我在SAP系统里哪个表是用来存储WM Level历史库存的. 这个问题问住了 ...

  4. Implemented the “Importance Sampling of Reflections from Hair Fibers”

      Just the indirect specular pass by importance sampling. With all layers. Manually traced by 3D Ham ...

  5. tornado 初解

    对于使用习惯Django的我来说,tornado实在是很简陋,没有那么多复杂的文件分类. 在tornado中,一个简单web只需要十几行简单的代码就OK了 import tornado.web imp ...

  6. 章节七、5-Maps

    一.向map集合中添加元素 map.put package ZangJie7; import java.util.HashMap; import java.util.Map; public class ...

  7. 产品经理说| AIOps 让告警变得更智能 (下)

    AIOps 人工智能和IT运营支撑 Ops 之间的故事,愈演愈烈,已经成为当今运维圈的热门话题,我打算从2篇文档分享我们在 AIOps 上一些探索和实践.(上篇)主要介绍了为什么事件(告警)处理需要 ...

  8. SQL server 2012 数据库日志缓存过大

    由于我公司的每日数据录入量较多,数据库日志与日俱增,前两天就出现了,因为数据库日志太大导致了 服务器磁盘空间不足,于是我上网查了一下,终于找到了一个数据库日志文件压缩的方法 原文出处:http://b ...

  9. Python的变量以及类型

    1.程序是用来处理数据的,变量就是用来存储数据的  num1 = 100 2.为了更充分的利用内存空间以及更有效率的管理内存,变量是有不同的类型 3.怎样知道一个变量的类型呢? 3.1 在python ...

  10. php伪协议,利用文件包含漏洞

    php支持多种封装协议,这些协议常被CTF出题中与文件包含漏洞结合,这里做个小总结.实验用的是DVWA平台,low级别,phpstudy中的设置为5.4.45版本, 设置allow_url_fopen ...