Netty4 学习笔记之一:客户端与服务端通信 demo
前言
因为以前在项目中使用过Mina框架,感受到了该框架的强大之处。于是在业余时间也学习了一下Netty。因为Netty的主要版本是Netty3和Netty4(Netty5已经被取消了),所以我就直接学习Netty4。在本文中演示的就是Netty的一个简单demo。
开发准备
Netty4的官方网站是:http://netty.io/ 。
本文使用的是Netty4.1。
由于Netty4.1版本需要JDK1.7,在使用JDK1.6时,会有一些bug,所以推荐使用JDK1.7。
因为Netty和Mina都是Trustin Lee的作品,所以在很多方面都十分相似,他们线程模型也是基本一致,采用了Reactors in threads模型,即Main Reactor + Sub Reactors的模式。
所以在开发上,很多都可以相互借鉴。
服务端
首先完成Netty服务端相关开发,和Mina一样。
主要由两个部分组成: 配置服务端的基本信息以及实现业务逻辑处理。
如果需要,还有filter过滤器。
服务端代码
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
*
* Title: NettyServer
* Description: Netty服务端
* Version:1.0.0
* @author Administrator
* @date 2017-8-31
*/
public class NettyServer {
private static final int port = 6789; //设置服务端端口
private static EventLoopGroup group = new NioEventLoopGroup(); // 通过nio方式来接收连接和处理连接
private static ServerBootstrap b = new ServerBootstrap();
/**
* Netty创建全部都是实现自AbstractBootstrap。
* 客户端的是Bootstrap,服务端的则是 ServerBootstrap。
**/
public static void main(String[] args) throws InterruptedException {
try {
b.group(group);
b.channel(NioServerSocketChannel.class);
b.childHandler(new NettyServerFilter()); //设置过滤器
// 服务器绑定端口监听
ChannelFuture f = b.bind(port).sync();
System.out.println("服务端启动成功...");
// 监听服务器关闭监听
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully(); ////关闭EventLoopGroup,释放掉所有资源包括创建的线程
}
}
}
服务端业务逻辑
import java.net.InetAddress;
import java.util.Date;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
*
* Title: HelloServerHandler
* Description: 服务端业务逻辑
* Version:1.0.0
* @author Administrator
* @date 2017-8-31
*/
public class NettyServerHandler extends SimpleChannelInboundHandler<String> {
/*
* 收到消息时,返回信息
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg)
throws Exception {
// 收到消息直接打印输出
System.out.println("服务端接受的消息 : " + msg);
if("quit".equals(msg)){//服务端断开的条件
ctx.close();
}
Date date=new Date();
// 返回客户端消息
ctx.writeAndFlush(date+"\n");
}
/*
* 建立连接时,返回消息
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("连接的客户端地址:" + ctx.channel().remoteAddress());
ctx.writeAndFlush("客户端"+ InetAddress.getLocalHost().getHostName() + "成功与服务端建立连接! \n");
super.channelActive(ctx);
}
}
服务端过滤器
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
/**
*
* Title: HelloServerInitializer
* Description: Netty 服务端过滤器
* Version:1.0.0
* @author Administrator
* @date 2017-8-31
*/
public class NettyServerFilter extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline ph = ch.pipeline();
// 以("\n")为结尾分割的 解码器
ph.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
// 解码和编码,应和客户端一致
ph.addLast("decoder", new StringDecoder());
ph.addLast("encoder", new StringEncoder());
ph.addLast("handler", new NettyServerHandler());// 服务端业务逻辑
}
}
客户端
客户端的主要工作是
1,连接到服务端
2,向服务端发送数据数据
3,处理服务端返回的数据
4,关闭连接
而且客户端相关代码也和服务端类似。
客户端
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.io.IOException;
/**
*
* Title: NettyClient
* Description: Netty客户端
* Version:1.0.0
* @author Administrator
* @date 2017-8-31
*/
public class NettyClient {
public static String host = "127.0.0.1"; //ip地址
public static int port = 6789; //端口
/// 通过nio方式来接收连接和处理连接
private static EventLoopGroup group = new NioEventLoopGroup();
private static Bootstrap b = new Bootstrap();
private static Channel ch;
/**
* Netty创建全部都是实现自AbstractBootstrap。
* 客户端的是Bootstrap,服务端的则是 ServerBootstrap。
**/
public static void main(String[] args) throws InterruptedException, IOException {
System.out.println("客户端成功启动...");
b.group(group);
b.channel(NioSocketChannel.class);
b.handler(new NettyClientFilter());
// 连接服务端
ch = b.connect(host, port).sync().channel();
star();
}
public static void star() throws IOException{
String str="Hello Netty";
ch.writeAndFlush(str+ "\r\n");
System.out.println("客户端发送数据:"+str);
}
}
客户端业务逻辑实现
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
*
* Title: NettyClientHandler
* Description: 客户端业务逻辑实现
* Version:1.0.0
* @author Administrator
* @date 2017-8-31
*/
public class NettyClientHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("客户端接受的消息: " + msg);
}
//
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("正在连接... ");
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("连接关闭! ");
super.channelInactive(ctx);
}
}
客户端过滤器
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
/**
*
* Title: NettyClientFilter
* Description: Netty客户端 过滤器
* Version:1.0.0
* @author Administrator
* @date 2017-8-31
*/
public class NettyClientFilter extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline ph = ch.pipeline();
/*
* 解码和编码,应和服务端一致
* */
ph.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
ph.addLast("decoder", new StringDecoder());
ph.addLast("encoder", new StringEncoder());
ph.addLast("handler", new NettyClientHandler()); //客户端的逻辑
}
}
效果实现图
服务端
客户端
demo教程到这里就结束了,如果有什么问题,欢迎提出!
该项目我放在github上了,有兴趣的可以看看!https://github.com/xuwujing/Netty
Netty4 学习笔记之一:客户端与服务端通信 demo的更多相关文章
- Docker学习笔记 - Docker客户端和服务端
学习内容: Docker客户端和服务端的通讯方式:client和自定义程序 Docker客户端和服务端的连接方式:socket 演示Docker客户端和服务端之间用remote-api通讯:nc ...
- FastSocket学习笔记~再说客户端与服务端的组成
废话多说 很久之前,我写过几篇FastSocket的文章,基本属于使用的方法,而缺乏对概念的总结讲解,而本讲就是弥补一下上几讲的不足,将核心的模块再说说,再谈谈,再聊聊! 首先FastSocket由C ...
- Netty4 学习笔记之四: Netty HTTP服务的实现
前言 目前主流的JAVA web 的HTTP服务主要是 springMVC和Struts2,更早的有JSP/servlet. 在学习Netty的时候,发现Netty 也可以作HTTP服务,于是便将此整 ...
- Android BLE与终端通信(三)——客户端与服务端通信过程以及实现数据通信
Android BLE与终端通信(三)--客户端与服务端通信过程以及实现数据通信 前面的终究只是小知识点,上不了台面,也只能算是起到一个科普的作用,而同步到实际的开发上去,今天就来延续前两篇实现蓝牙主 ...
- 基于开源SuperSocket实现客户端和服务端通信项目实战
一.课程介绍 本期带给大家分享的是基于SuperSocket的项目实战,阿笨在实际工作中遇到的真实业务场景,请跟随阿笨的视角去如何实现打通B/S与C/S网络通讯,如果您对本期的<基于开源Supe ...
- Netty入门之客户端与服务端通信(二)
Netty入门之客户端与服务端通信(二) 一.简介 在上一篇博文中笔者写了关于Netty入门级的Hello World程序.书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码 ...
- Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令.
Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令. 一丶socket套接字 什么是socket套接字: 专业理解: socket是应用层与TCP/IP ...
- netty-3.客户端与服务端通信
(原) 第三篇,客户端与服务端通信 以下例子逻辑: 如果客户端连上服务端,服务端控制台就显示,XXX个客户端地址连接上线. 第一个客户端连接成功后,客户端控制台不显示信息,再有其它客户端再连接上线,则 ...
- Netty4 学习笔记之二:客户端与服务端心跳 demo
前言 在上一篇Netty demo 中,了解了Netty中的客户端和服务端之间的通信.这篇则介绍Netty中的心跳. 之前在Mina 中心跳的使用是通过继承 KeepAliveMessageFacto ...
随机推荐
- 【Tomcat】batch获得war包
功能: 将maven项目打包复制到tomcat/webapps set git=C:\Users\zhengwenqiang\git set tomcat=e:\tomcat7.0.64 c: cd ...
- C++11 学习 间隔更新中
1.*this 返回执行它的的对象的引用,this返回的是地址,这涉及C++对象模式有可能是对象的首地址,有可能是首地址加上虚表的长度, 一般是*this ,有不同意见的可以提出来讨论 2.初始化列表 ...
- 读懂javascript深拷贝与浅拷贝
1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...
- Win7里面如何把这一堆图标放进那个右下角的小三角框框
Win7里面如何把这一堆图标放进那个右下角的小三角框框.. Win7里面如何把这一堆图标放进那个小框框:1.在任务栏空白处右击,点击属性:2.在属性中的通知区域-->点击自定义按钮:3.去除勾选 ...
- WeQuant交易策略—Chaikin A/D
策略名称:AD指标策略 多空双方力量浮标- AD(Chaikin A/D线)策略关键词:ChaikinA/D线.多空对比.AD指标是一种非常流行的平横交易量指标, 用于估定一段时间内该证券累积的资金流 ...
- 配置IIS使用Python
打开IIS管理器 选择功能视图,然后选择ISAPI和CGI限制 打开后,在右侧操作,点击添加,会出现下图所示 按图中提示填写相应部分,在选择路径时,默认可能是dll文件,改成全部文件即可,然后再选择p ...
- 报表 jasper + ireport5.6
下载 iReport-5.6.0,jdk7,以及众多lib , 这里我提供下资源(我的百度云) 安装好iReport-5.6.0和jdk7, 在安装目录的\etc\ireport.conf,修改其中 ...
- Wireshark使用drcom_2011.lua插件协助分析drcom协议
drcom_2011.lua是来源于Google code上的一个开源项目中的一个插件,感谢网络大神的分享 需要使用drcom_2011.lua分析drcom协议的话,需要把drcom_2011.lu ...
- Linux平台 Oracle 12cR2 RAC安装Part1:准备工作
Linux平台 Oracle 12cR2 RAC安装Part1:准备工作 一.实施前期准备工作 1.1 服务器安装操作系统 1.2 Oracle安装介质 1.3 共享存储规划 1.4 网络规范分配 二 ...
- C语言格式化输入输出
%i和%d之间的区别 作为匹配整数的转换说明,printf格式串中两者并没有区别,但是在scanf格式串中%d只能匹配十位制整数,而%i可以匹配八进制(前缀为0,如086).十进制或十六进制(前缀0x ...