netty 学习 (1)
1、Client向Server发送消息:Are you ok?
2、Server接收客户端发送的消息,并打印出来。
3、Server端向客户端发送消息:I am ok!
4、Client接收Server端发送的消息,并打印出来,通讯结束。
涉及到的类有4个:
1、HelloServer :server类,启动Netty server
2、HelloServerInHandler:server的handler,接收客户端消息,并向客户端发送消息
3、HelloClient:client类,建立于Netty server的连接
4、HelloClientIntHandler:client的handler,接收server端的消息,并向服务端发送消息
一、先加入必要的类库:
二、HelloServer代码如下:
package com.yao.netty;
importio.netty.bootstrap.ServerBootstrap;
importio.netty.channel.ChannelFuture;
importio.netty.channel.ChannelInitializer;
importio.netty.channel.ChannelOption;
importio.netty.channel.EventLoopGroup;
importio.netty.channel.nio.NioEventLoopGroup;
importio.netty.channel.socket.SocketChannel;
importio.netty.channel.socket.nio.NioServerSocketChannel;
publicclassHelloServer {
publicvoidstart(int port) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)
.childHandler(newChannelInitializer<SocketChannel>() {
@Override
publicvoidinitChannel(SocketChannel ch)
throws Exception {
// 注册handler
ch.pipeline().addLast(newHelloServerInHandler());
}
}).option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f =b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
publicstaticvoidmain(String[] args) throws Exception {
HelloServer server = new HelloServer();
server.start(8000);
}
}
三、 HelloServerInHandler代码如下:
package com.yao.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
importorg.apache.commons.logging.Log;
importorg.apache.commons.logging.LogFactory;
// 该handler是InboundHandler类型
public class HelloServerInHandlerextends ChannelInboundHandlerAdapter {
private static Log logger = LogFactory.getLog(HelloServerInHandler.class);
@Override
public void channelRead(ChannelHandlerContextctx, Object msg)
throws Exception {
logger.info("HelloServerInHandler.channelRead");
ByteBuf result = (ByteBuf) msg;
byte[] result1 = new byte[result.readableBytes()];
// msg中存储的是ByteBuf类型的数据,把数据读取到byte[]中
result.readBytes(result1);
String resultStr = new String(result1);
// 接收并打印客户端的信息
System.out.println("Client said:" + resultStr);
// 释放资源,这行很关键
result.release();
// 向客户端发送消息
String response = "I am ok!";
// 在当前场景下,发送的数据必须转换成ByteBuf数组
ByteBuf encoded = ctx.alloc().buffer(4 * response.length());
encoded.writeBytes(response.getBytes());
ctx.write(encoded);
ctx.flush();
}
@Override
public void channelReadComplete(ChannelHandlerContextctx) throws Exception {
ctx.flush();
}
}
四、HelloClient代码如下:
package com.yao.netty;
importio.netty.bootstrap.Bootstrap;
importio.netty.channel.ChannelFuture;
importio.netty.channel.ChannelInitializer;
importio.netty.channel.ChannelOption;
importio.netty.channel.EventLoopGroup;
importio.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
importio.netty.channel.socket.nio.NioSocketChannel;
publicclassHelloClient {
publicvoidconnect(String host, int port) throws Exception {
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(workerGroup).channel(NioSocketChannel.class).option(ChannelOption.SO_KEEPALIVE,true)
.handler(newChannelInitializer<SocketChannel>() {
@Override
publicvoidinitChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(newHelloClientIntHandler());
}
});
// Start the client.
ChannelFuture f = b.connect(host,port).sync();
// Wait until the connection isclosed.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
publicstaticvoidmain(String[] args) throws Exception {
HelloClient client = new HelloClient();
client.connect("127.0.0.1", 8000);
}
}
五、 HelloClientIntHandler代码如下:
package com.yao.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
importorg.apache.commons.logging.Log;
importorg.apache.commons.logging.LogFactory;
public class HelloClientIntHandlerextends ChannelInboundHandlerAdapter {
private static Log logger = LogFactory.getLog(HelloClientIntHandler.class);
// 接收server端的消息,并打印出来
@Override
public void channelRead(ChannelHandlerContextctx, Object msg) throws Exception {
logger.info("HelloClientIntHandler.channelRead");
ByteBufresult = (ByteBuf) msg;
byte[] result1 = new byte[result.readableBytes()];
result.readBytes(result1);
System.out.println("Server said:" + new String(result1));
result.release();
}
// 连接成功后,向server发送消息
@Override
public void channelActive(ChannelHandlerContextctx) throws Exception {
logger.info("HelloClientIntHandler.channelActive");
String msg = "Are you ok?";
ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());
encoded.writeBytes(msg.getBytes());
ctx.write(encoded);
ctx.flush();
}
}
六、还有log4j.xml文件:
<?xml version="1.0"?>
<!DOCTYPElog4j:configuration SYSTEM "log4j.dtd">
<log4j:configurationxmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p] [%d] [%t][%c] %m%n"/>
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="./log/netty.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p] [%d] [%t][%c] %m%n"/>
</layout>
</appender>
<appender name="FILE_ERR" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="./log/netty_err.log"/>
<param name="Threshold" value="ERROR" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p] [%d] [%t][%c] %m%n"/>
</layout>
</appender>
<logger name="io.netty" additivity="false">
<level value="INFO,DEBUG" />
<appender-refref="FILE" />
<appender-refref="FILE_ERR" />
<appender-refref="CONSOLE" />
</logger>
<logger name="com.yao" additivity="false">
<level value="INFO,DEBUG" />
<appender-refref="FILE" />
<appender-refref="FILE_ERR" />
<appender-refref="CONSOLE" />
</logger>
<root>
<level value="debug"/>
<appender-refref="FILE"/>
<appender-refref="CONSOLE"/>
<appender-refref="FILE_ERR" />
</root>
</log4j:configuration>
总结:
通过上面简单的实例可以发现:
1、在没有任何encoder、decoder的情况下,Netty发送接收数据都是按照ByteBuf的形式,其它形式都是不合法的。
2、接收发送数据操作都是通过handler实现的,handler在netty中占据了非常重要的位置。
3、netty的handler是基于事件触发的,例如当client连接server成功后,client中的HelloClientIntHandler的channelActive方法会自动调用。
netty 学习 (1)相关推荐
- Netty学习笔记(二) 实现服务端和客户端
在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...
- Netty 学习和进阶策略
https://www.infoq.cn/article/xt9*7K4fJktiuWTLYrZS 背景 Netty 框架的特点 Netty 的一个特点就是入门相对比较容易,但是真正掌握并精通是非常困 ...
- Netty学习笔记(六)Pipeline的传播机制
前面简单提到了下Pipeline的传播机制,这里再详细分析下 Pipeline的传播机制中有两个非常重要的属性inbound和outbound(AbstractChannelHandlerContex ...
- Netty学习笔记(二)Netty服务端流程启动分析
先贴下在NIO和Netty里启动服务端的代码 public class NioServer { /*** 指定端口号启动服务* */public boolean startServer(int por ...
- Netty学习开发之路
Netty学习 前言简介 ======= 我们公司最近决定做个基于netty tcp的IM程序,由于最近项目比较紧张,所以没办法,只能我和另外一个做安卓的同事一起学习开发.在这里先说一句瓜皮呦!而且项 ...
- 1、张龙netty学习 第一个netty服务端
张龙netty学习 第一个netty服务端 public class TestServer {public static void main(String[] args) throws Excepti ...
- 04、Netty学习笔记—(黏包半包及协议设计解析)
文章目录 一.粘包与半包 1.1.现象分析 1.1.1.粘包.半包情况分析 1.1.2.滑动窗口.MSS限制.Nagle算法介绍 1.2.粘包.半包现象复现 1.2.1.粘包复现 1.2.2.半包复现 ...
- Netty学习(一):初识Netty
章节 1.Netty学习(一):初识Netty 2.Netty学习(二):Netty的核心组件 3.Netty学习(三):Netty的流程分析 4.Netty学习(四):Netty零拷贝(转载) 5. ...
- Netty学习笔记:二、NIO网络应用实例-群聊系统
实例要求: 编写一个NIO群聊系统,实现服务器端和多个客户端之间的数据简单通讯(非阻塞): 实现多人群聊: 服务器端:可以监测用户上线.离线,并实现消息转发功能: 客户端:通过channel可以无阻塞 ...
- Netty,Tcp,socket的java框架,netty学习
最新更新,报文发送,机器终端(车)与服务端 先学习一下基本内容,以下是基于基本内容 互相转换:byte(字节,字节是数字单位,他的数组是十进制内容),bit(二进制内容,不用操心这部分),十六进制0x ...
最新文章
- 深度学总结:skip-gram pytorch实现
- java进出栈_JVM函数调用:Java出入栈
- BUUCTF-WEB:[HCTF 2018]WarmUp
- 使用xUnit为.net core程序进行单元测试(中)
- DB2常用傻瓜问题1000问(之一)
- java biginteger 比较大小,java – 打印非常大的BigIntegers
- 2022蓝骑士发展与保障报告
- 用python计算1~100的阶乘之和_在Python中递归函数调用举例and匿名函数lambda求1~100的和及计算阶乘举例...
- 怎么用html做随机颜色,JavaScript 实现网站标签随机颜色的方法
- js中filter函数
- 如何在PPT中制作动态图表,学会这种方法实在太简单
- 软考计算机英语词汇,软考计算机专业英语常用词汇(首字母I-O)
- vue打包时页面布局出现混乱
- Mysql修改服务中可执行文件路径
- php 发socket数据库,php socket连接数据库
- Centos下安装桌面环境和Flash插件
- LED驱动电源EMI整改方案
- 知识图谱核心技术(一):知识图谱的概述
- Windows常用的快捷键 让妹子办公效率速提升
- 中国IT领袖峰会 以5G与人工智能为主题