在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学习笔记(二) 实现服务端和客户端的更多相关文章

  1. 红帽学习笔记[RHCE]OpenLDAP 服务端与客户端配置

    目录 OpenLDAP 服务端与客户端配置 关于LDIF 一个LDIF基本结构一个条目 属性 Object的类型 服务端 安装 生成证书 生成默认数据 修改基本的配置 导入基础数据 关于ldif的格式 ...

  2. Netty学习笔记(二)——netty组件及其用法

    1.Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 原生NIO存在的问题 1) NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.Se ...

  3. 《精通并发与Netty》学习笔记(02 - 服务端程序编写)

    上节我们介绍了开发netty项目所必需的开发环境及工具的使用,这节我们来写第一个netty项目 开发步骤 第一步:打开https://search.maven.org 找到netty依赖库 第二步:打 ...

  4. Netty学习笔记(二)

    只是代码,建议配合http://ifeve.com/netty5-user-guide/此网站观看 package com.demo.netty; import org.junit.Before;im ...

  5. Kafka学习笔记2--Kafka的服务端配置

    下载解压 kafka 后,在 kafka/config 下有 3 个配置文件与主题的生产.消费相关. server.properties--服务端配置 producer.properties--生产端 ...

  6. dubbo学习笔记二(服务调用)

    项目结构 代码示例 由于之前的IEchoService 的一个方法只是在服务端控制台打印,不便在浏览器测试,所以新添加的方法 api和服务端代码变更 public interface IEchoSer ...

  7. SVN1.6服务端和客户端安装配置指导

    本节向大家描述SVN1.6服务端和客户端安装配置步骤,随着SVN的快速发展,版本也进行了升级更新,本节就和大家一起学习一下SVN1.6服务端和客户端安装配置步骤,欢迎大家一起来学习.下面是具体介绍.1 ...

  8. Netty 学习(二):服务端与客户端通信

    Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...

  9. Netty 学习(一):服务端启动 & 客户端启动

    Netty 学习(一):服务端启动 & 客户端启动 作者: Grey 原文地址: 博客园:Netty 学习(一):服务端启动 & 客户端启动 CSDN:Netty 学习(一):服务端启 ...

随机推荐

  1. 爱奇艺技术分享:爱奇艺Android客户端启动速度优化实践总结

    本文由爱奇艺技术团队原创分享,原题<爱奇艺Android客户端启动优化与分析>. 1.引言 互联网领域里有个八秒定律,如果网页打开时间超过8秒,便会有超过70%的用户放弃等待,对Andro ...

  2. [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 ...

  3. [Swift]LeetCode986. 区间列表的交集 | Interval List Intersections

    Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted order ...

  4. 我们为什么要搞长沙.NET技术社区?

    我们为什么要搞长沙.NET技术社区? 感谢大家的关注,请允许我冒昧的向大家汇报长沙.NET技术社区第一次交流会的会议进展情况. 活动过程汇报 2019年2月17日,继深圳,广州,西安,成都,苏州相继成 ...

  5. 面试中程序员常见的Redis"刁难"问题,值得一读!

    导读 在程序员面试过程中Redis相关的知识是常被问到的话题.作为一名在互联网技术行业打击过成百上千名的资深技术面试官,总结了面试过程中经常问到的问题.十分值得一读. Redis有哪些数据结构? 字符 ...

  6. 火狐l浏览器所有版本

    最近在群里看到好多人需要火狐浏览器的低版本,而且都是跪求,更有甚者是高额悬赏,因此给大家一个链接,免费的,免费的,免费的!!!重要的事说三遍,拿走不谢~~ 火狐所有版本,了解一下,有需要的自行下载. ...

  7. lambda表达式中的排序问题

    新月新气象,10月第一篇,这也是我工作的第一天,这一篇文章我们要讲到lambda的排序问题 我是这样排序的 var list = DB.company.OrderBy(x=>x.isfreeze ...

  8. Android Native App自动化测试实战讲解(下)(基于python)

    6.Appuim自动化测试框架API讲解与案例实践(三) 如图1,可以在主函数里通过TestSuite来指定执行某一个测试用例: 6.1,scroll():如图2 从图3中可以看到当前页面的所有元素r ...

  9. 知识小罐头03(idea+maven+部署war包到tomcat 上)

    自学的的小伙伴第一就要用maven!自学的的小伙伴第一就要用maven!自学的的小伙伴第一就要用maven! 重要的事说三遍!maven本质上,其实就是一种目录的格式,没有什么特别的地方!而且,你可以 ...

  10. Unity实现c#热更新方案探究(一)

    转载请标明出处:http://www.cnblogs.com/zblade/ 最近研究了一下如何在unity中实现c#的热更新,对于整个DLL热更新的过程和方案有一个初步的了解,这儿就写下来,便于后续 ...