实现一个功能,客户端和服务器 轮流对一个数加+1

服务器

public class Server {
public static void main(String[] args) {
NioEventLoopGroup boss=new NioEventLoopGroup(1);
NioEventLoopGroup worker=new NioEventLoopGroup(3);
try {
final ServerBootstrap server=new ServerBootstrap();
server.group(boss,worker).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ServerHandler());
}
});
ChannelFuture future = server.bind(8881).sync();
future.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}
finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}

服务器handler

netty ChannelHandler 类似 spring mvc的filter,使用的是责任链模式,可以对客户端传来的数据进行层层解析,解码等操作。

在没有任何特殊操作下,默认传递在责任中的对象是ByteBuf

public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//msg 其实就是个ByteBuf 对象
ByteBuf buf=(ByteBuf) msg;
int i = buf.readInt();
System.out.println("服务器收到客户端消息"+ctx.channel().remoteAddress()+" "+i);
ByteBuf newbuf=ctx.alloc().buffer(1024);
newbuf.writeInt(i+1);
ctx.writeAndFlush(newbuf);
buf.release();
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel active");
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}

客户端

public class Client {
public static void main(String[] args) {
NioEventLoopGroup boss=new NioEventLoopGroup(1);
try {
final Bootstrap client=new Bootstrap();
client.group(boss).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ClientHandler());
}
});
ChannelFuture future = client.connect("127.0.0.1",8881).sync();
future.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}
finally {
boss.shutdownGracefully();
}
}
}

客户端handlr

public class ClientHandler extends SimpleChannelInboundHandler {
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf=(ByteBuf)msg;
int i=buf.readInt();
System.out.println("客服端收到服务器"+ctx.channel().remoteAddress()+"---> "+i);
Thread.sleep(2000);
ByteBuf newbuf = ctx.alloc().buffer(1024);
newbuf.writeInt(i+1);
ctx.writeAndFlush(newbuf);
} @Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("连接服务器成功");
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ByteBuf buffer = ctx.alloc().buffer(1024);
buffer.writeInt(1);
ctx.writeAndFlush(buffer);
}
}

一开始很疑惑,channelRead0(ChannelHandlerContext ctx, Object msg) 方法里的msg 到底是个什么对象?
在添加其它handler之后,比如一个StringDecode,netty会自动的把ByteBuf里的字节转String,并传递在Object对象中。这是Object就是一个String。
翻了下源码,还是很清晰的
在ChannelHandlerContext 接口中有一个fireChannelRead 方法,这个方法的解释如下
> ChannelHandlerContext fireChannelRead(java.lang.Object msg)
Description copied from interface: ChannelInboundInvoker
A Channel received a message. This will result in having the ChannelInboundHandler.channelRead(ChannelHandlerContext, Object) method called of the next ChannelInboundHandler contained in the ChannelPipeline of the Channel.
Specified by:
fireChannelRead in interface ChannelInboundInvoker

简单来就是会调用handler 责任链的下一个处理类。同过fireChannelRead方法,可以给下一个责任链传递一个对象msg,这个msg会传递到下一个处理类的 ChannelRead方法上。例如,StringDecode把ByteBuf转为一个String对象msg,在调用fireChannelRead(msg),就把这个String传到下一个handler去了。

channelRead0也是同样的意思


netty是基于nio的框架,要是理解了nio,其实操作起来也不是很费劲。

JAVA netty 简单使用的更多相关文章

  1. Netty——简单创建服务器、客户端通讯

    Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用.Netty相当简化和流线化了网络应用的编程开发过程 ...

  2. Java实现简单的RPC框架(美团面试)

    一.RPC简介 RPC,全称为Remote Procedure Call,即远程过程调用,它是一个计算机通信协议.它允许像调用本地服务一样调用远程服务.它可以有不同的实现方式.如RMI(远程方法调用) ...

  3. 学习 java netty (一) -- java nio

    前言:近期在研究java netty这个网络框架,第一篇先介绍java的nio. java nio在jdk1.4引入,事实上也算比較早的了.主要引入非堵塞io和io多路复用.内部基于reactor模式 ...

  4. Java实现简单RPC框架(转)

    一.RPC简介 RPC,全称Remote Procedure Call, 即远程过程调用,它是一个计算机通信协议.它允许像本地服务一样调用远程服务.它可以有不同的实现方式.如RMI(远程方法调用).H ...

  5. java netty socket库和自定义C#socket库利用protobuf进行通信完整实例

    之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...

  6. Java实现简单版SVM

    Java实现简单版SVM 近期的图像分类工作要用到latent svm,为了更加深入了解svm,自己动手实现一个简单版的.         之所以说是简单版,由于没实用到拉格朗日,对偶,核函数等等.而 ...

  7. java实现简单的单点登录

    java实现简单的单点登录 摘要:单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统当中.本文从业务的角度分析了单点登录的需求和应用领域:从技术本身的角度分析了单点登录技术的内部机制和实现 ...

  8. Java自定义简单标签

     Java自定义简单标签可以方便的在页面输出信息,并且对于权限的控制,和对于Jsp标签和servlet代码的分离有着很好的作用. 下面将以权限的控制为例自定义一个标签: 一.标签类型 <wxt: ...

  9. 主题:Java WebService 简单实例

    链接地址:主题:Java WebService 简单实例    http://www.iteye.com/topic/1135747 前言:朋友们开始以下教程前,请先看第五大点的注意事项,以避免不必要 ...

随机推荐

  1. WordPress后台地址路径修改方法

    用过WordPress后台的,其实都知道http://域名目录/wp-login.php就是登录地址,如果这时候使用暴力破解,很可能破解密码(这就有些想象力了),下面芝麻带你看看如何自定义美观的地址. ...

  2. 小型APP系统开发与应用项目实训

    实训项目 :             小型APP系统开发与应用项目实训                           项目成品名称:          果乐多商城               项 ...

  3. Spring 梳理 - WebMvcConfigurerAdapter详解

    参考:https://blog.csdn.net/weixin_43453386/article/details/83623242

  4. mysql uuid使用

    java中可以使用UUID类来生成uuid,使用mysql也可以使用UUID函数来获取uuid,如 select UUID(); 也可以对查询的结果做一些处理,比如说将"-"替换成 ...

  5. Axure实现banner功能

    1.添加一个动态面板,添加上一张.下一张及当前banner对应的序号圆圈,如图所示: 当添加好元素后,实现自动轮播:点击[轮播图面板]页面:选中动态面板:右边添加事件编辑栏——属性——载入时——添加动 ...

  6. 【SQL server初级】SQL索引(一)

    SQL索引[一](此文章为“数据库性能优化二:数据库表优化”附属文章之一) SQL索引在数据库优化中占有一个非常大的比例, 一个好的索引的设计,可以让你的效率提高几十甚至几百倍,在这里将带你一步步揭开 ...

  7. php无限级分类实战——评论及回复功能

    经常在各大论坛或新闻板块详情页面下边看到评论功能,当然不单单是直接发表评论内容那么简单,可以对别人的评论进行回复,别人又可以对你的回复再次评论或回复,如此反复,理论上可以说是没有休止,从技术角度分析很 ...

  8. Go标准库Context

    在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理.请求处理函数通常会启动额外的 goroutine 用来访问后端服务,比如数据库和RPC服务.用来处理一个请 ...

  9. 色即是空,空即是色---java有关null的几件小事

    故事背景 ---摩诃般若波罗蜜多心经: 观自在菩萨,行深般若波罗蜜多时,照见五蕴皆空,度一切苦厄.舍利子,色不异空,空不异色:色即是空,空即是色.受想行识,亦复如是.舍利子,是诸法空相,不生不灭,不垢 ...

  10. C++set 和 multiset的使用

    最后一个自由支配的暑假,学一些自己感兴趣的部分,也算为大三作准备. C++中set集合的使用 定义一个int类型的集合 set<int> s: set<int>::iterat ...