Netty学习笔记(二) 实现服务端和客户端
在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求。
前置工作
开发环境
- JDK8
- Netty版本:5.0.0.Alpha2
- 集成环境:IDEA
- 构建工具:Gradle
依赖
compile group: 'io.netty', name: 'netty-all', version: '5.0.0.Alpha2'
compile group: 'org.projectlombok', name: 'lombok', version: '1.18.0'
服务端
Netty服务器主要由两部分组成:
- 配置服务器功能,如线程、端口
- 实现服务器处理程序
服务端HandleAdapter
我们是首先实现服务端处理程序,实现Handle要求继承HandleAdapter,这里我们继承SimpleChannelInboundHandler<T>,下面是具体实现的代码信息,其每个函数的作用,我们只需要重写我们所需要的方法即可。
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
* Netty 服务Handle
*
* @author tao
*/
@ChannelHandler.Sharable
public class EchoServiceHandle extends SimpleChannelInboundHandler<String> {
/**
* 接收到新的消息
* @param ctx
* @param msg
* @throws Exception
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// 打印接收到的消息
System.out.println("Netty服务端接收到消息 " + msg);
// 回复消息
ctx.channel().writeAndFlush("Send ----> 客户端" + ctx.channel().id() + "你好,我已经接收到你发送的消息");
}
/**
* 有新的连接加入
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("接入新的Channel,id = " + ctx.channel().id());
}
/**
* 服务端发生异常信息的时候
* @param ctx
* @param cause
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// 服务端发生异常
System.out.println("Netty 服务端发生异常 ,异常信息:" + cause);
ctx.close();
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, String msg) {}
}
服务端启动
在服务端的EchoServiceHandle完成之后,我们需要配置服务器的参数信息,比如端口等
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import lombok.Data;
/**
* @author tao
*/
@Data
public class EchoService {
private int port;
public void start() throws Exception {
EventLoopGroup boosGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap
.group(boosGroup, workGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.childHandler(
new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//字符串解码器
pipeline.addLast(new StringDecoder());
//字符串编码器
pipeline.addLast(new StringEncoder());
//服务端处理器
pipeline.addLast(new EchoServiceHandle());
}
});
ChannelFuture sync = bootstrap.bind(port).sync();
System.out.println("Netty Service start with " + port + "...");
sync.channel().closeFuture().sync();
} finally {
workGroup.shutdownGracefully();
boosGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
EchoService service = new EchoService();
service.setPort(8080);
service.start();
}
}
启动后,我们可以看到启动信息如下:
Netty Service start with 8080...
客户端
客户端和服务端类似,可以相互参考学习.
客户端HandleAdapter
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
@ChannelHandler.Sharable
public class EchoClientHandle extends SimpleChannelInboundHandler<String> {
/**
* 连接创建成功的时候
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channelActive");
//连接成功后向服务端发送问候消息
ctx.channel().writeAndFlush(Unpooled.copiedBuffer("你好,这里是Netty客户端", CharsetUtil.UTF_8));
}
/**
* 发生异常
* @param ctx
* @param cause
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
System.out.println("exceptionCaught");
cause.printStackTrace();
ctx.close();
}
/**
* 接收到服务端发过来的数据
* @param ctx
* @param msg
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
//打印接收到的数据信息
System.out.println("channelRead = " + msg);
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, String msg) {}
}
客户端启动
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
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.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.net.InetSocketAddress;
/** @author tao */
@Data
@Accessors(chain = true)
@Slf4j
public class EchoClient {
private int port;
private String host;
public void start() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap
.group(group)
.channel(NioSocketChannel.class)
.handler(
new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// 字符串解码器
pipeline.addLast(new StringDecoder());
// 字符串编码器
pipeline.addLast(new StringEncoder());
pipeline.addLast(new EchoClientHandle());
}
});
ChannelFuture sync = bootstrap.connect(new InetSocketAddress(host, port)).sync();
sync.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
group.shutdownGracefully().sync();
}
}
public static void main(String[] args) throws Exception {
EchoClient client = new EchoClient();
client.setHost("127.0.0.1").setPort(8080);
client.start();
}
}
效果
服务端效果
Netty Service start with 8080...
接入新的Channel,id = c0d4f037
Netty服务端接收到消息 你好,这里是Netty客户端
客户端效果
channelActive
channelRead = Send ----> 客户端c0d4f037你好,我已经接收到你发送的消息
Netty学习笔记(二) 实现服务端和客户端的更多相关文章
- 红帽学习笔记[RHCE]OpenLDAP 服务端与客户端配置
目录 OpenLDAP 服务端与客户端配置 关于LDIF 一个LDIF基本结构一个条目 属性 Object的类型 服务端 安装 生成证书 生成默认数据 修改基本的配置 导入基础数据 关于ldif的格式 ...
- Netty学习笔记(二)——netty组件及其用法
1.Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 原生NIO存在的问题 1) NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.Se ...
- 《精通并发与Netty》学习笔记(02 - 服务端程序编写)
上节我们介绍了开发netty项目所必需的开发环境及工具的使用,这节我们来写第一个netty项目 开发步骤 第一步:打开https://search.maven.org 找到netty依赖库 第二步:打 ...
- Netty学习笔记(二)
只是代码,建议配合http://ifeve.com/netty5-user-guide/此网站观看 package com.demo.netty; import org.junit.Before;im ...
- Kafka学习笔记2--Kafka的服务端配置
下载解压 kafka 后,在 kafka/config 下有 3 个配置文件与主题的生产.消费相关. server.properties--服务端配置 producer.properties--生产端 ...
- dubbo学习笔记二(服务调用)
项目结构 代码示例 由于之前的IEchoService 的一个方法只是在服务端控制台打印,不便在浏览器测试,所以新添加的方法 api和服务端代码变更 public interface IEchoSer ...
- SVN1.6服务端和客户端安装配置指导
本节向大家描述SVN1.6服务端和客户端安装配置步骤,随着SVN的快速发展,版本也进行了升级更新,本节就和大家一起学习一下SVN1.6服务端和客户端安装配置步骤,欢迎大家一起来学习.下面是具体介绍.1 ...
- Netty 学习(二):服务端与客户端通信
Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...
- Netty 学习(一):服务端启动 & 客户端启动
Netty 学习(一):服务端启动 & 客户端启动 作者: Grey 原文地址: 博客园:Netty 学习(一):服务端启动 & 客户端启动 CSDN:Netty 学习(一):服务端启 ...
随机推荐
- 爱奇艺技术分享:爱奇艺Android客户端启动速度优化实践总结
本文由爱奇艺技术团队原创分享,原题<爱奇艺Android客户端启动优化与分析>. 1.引言 互联网领域里有个八秒定律,如果网页打开时间超过8秒,便会有超过70%的用户放弃等待,对Andro ...
- [Swift]LeetCode365. 水壶问题 | Water and Jug Problem
You are given two jugs with capacities x and y litres. There is an infinite amount of water supply a ...
- [Swift]LeetCode986. 区间列表的交集 | Interval List Intersections
Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted order ...
- 我们为什么要搞长沙.NET技术社区?
我们为什么要搞长沙.NET技术社区? 感谢大家的关注,请允许我冒昧的向大家汇报长沙.NET技术社区第一次交流会的会议进展情况. 活动过程汇报 2019年2月17日,继深圳,广州,西安,成都,苏州相继成 ...
- 面试中程序员常见的Redis"刁难"问题,值得一读!
导读 在程序员面试过程中Redis相关的知识是常被问到的话题.作为一名在互联网技术行业打击过成百上千名的资深技术面试官,总结了面试过程中经常问到的问题.十分值得一读. Redis有哪些数据结构? 字符 ...
- 火狐l浏览器所有版本
最近在群里看到好多人需要火狐浏览器的低版本,而且都是跪求,更有甚者是高额悬赏,因此给大家一个链接,免费的,免费的,免费的!!!重要的事说三遍,拿走不谢~~ 火狐所有版本,了解一下,有需要的自行下载. ...
- lambda表达式中的排序问题
新月新气象,10月第一篇,这也是我工作的第一天,这一篇文章我们要讲到lambda的排序问题 我是这样排序的 var list = DB.company.OrderBy(x=>x.isfreeze ...
- Android Native App自动化测试实战讲解(下)(基于python)
6.Appuim自动化测试框架API讲解与案例实践(三) 如图1,可以在主函数里通过TestSuite来指定执行某一个测试用例: 6.1,scroll():如图2 从图3中可以看到当前页面的所有元素r ...
- 知识小罐头03(idea+maven+部署war包到tomcat 上)
自学的的小伙伴第一就要用maven!自学的的小伙伴第一就要用maven!自学的的小伙伴第一就要用maven! 重要的事说三遍!maven本质上,其实就是一种目录的格式,没有什么特别的地方!而且,你可以 ...
- Unity实现c#热更新方案探究(一)
转载请标明出处:http://www.cnblogs.com/zblade/ 最近研究了一下如何在unity中实现c#的热更新,对于整个DLL热更新的过程和方案有一个初步的了解,这儿就写下来,便于后续 ...