Netty入门之客户端与服务端通信(二)
Netty入门之客户端与服务端通信(二)
一.简介
在上一篇博文中笔者写了关于Netty入门级的Hello World程序。书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码吧。
二.客户端与服务端的通信
2.1 服务端启动程序
public class MyServer {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try{
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new MyInitializer());
ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
channelFuture.channel().closeFuture().sync();
}finally{
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
2.2 服务端通道初始化程序
public class MyInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
/**
* LengthFieldBasedFrameDecoder: 基于长度属性的帧解码器。
* 客户端传递过来的数据格式为:
* BEFORE DECODE (14 bytes) AFTER DECODE (14 bytes)
* +--------+----------------+ +--------+----------------+
* | Length | Actual Content |----->| Length | Actual Content |
* | 0x000C | "HELLO, WORLD" | | 0x000C | "HELLO, WORLD" |
* +--------+----------------+ +--------+----------------+
* 5个参数依次为:1.(maxFrameLength)每帧数据的最大长度.
* 2.(lengthFieldOffset)length属性在帧中的偏移量。
* 3.(lengthFieldLength)length属性的长度,需要与客户端 LengthFieldPrepender设置的长度一致,
* 值的取值只能为1, 2, 3, 4, 8
* 4.(lengthAdjustment)长度调节值, 当信息长度包含长度时候,用于修正信息的长度。
* 5.(initialBytesToStrip)在获取真实的内容的时候,需要忽略的长度(通常就是length的长度)。
*
* 参考: http://blog.csdn.net/educast/article/details/47706599
*/
pipeline.addLast("lengthFieldBasedFrameDecoder",
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 2, 0, 2));
/**
* LengthFieldPrepender: length属性在帧中的长度。只能为1,2,3,4,8。
* 该值与对应的客户端(或者服务端)在解码时候使用LengthFieldBasedFrameDecoder中所指定的lengthFieldLength
* 的值要保持一致。
*/
pipeline.addLast("lengthFieldPrepender", new LengthFieldPrepender(3));
//StringDecoder字符串的解码器, 主要用于处理编码格式
pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
//StringDecoder字符串的编码器,主要用于指定字符串的编码格式
pipeline.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast(new MyHandler()); //自定义的Handler
}
}
2.3 自定义Handler
public class MyHandler extends SimpleChannelInboundHandler<String>{
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println(ctx.channel().remoteAddress() + ":" + msg);
ctx.channel().writeAndFlush("from server: 草泥马");
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println(System.currentTimeMillis() + "********");
System.out.println("server handler added**********");
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println(System.currentTimeMillis() + "********");
System.out.println("server channel register****");
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println(System.currentTimeMillis() + "********");
System.out.println("server channel actieve****");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
2.4客户端启动程序
public class MyClient {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try{
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new ClientInitializer());
ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 8899).sync();
channelFuture.channel().closeFuture().sync();
}finally{
eventLoopGroup.shutdownGracefully();
}
}
}
2.5客户端通道初始化
public class ClientInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("lengthFieldBasedFrameDecoder",
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 2, 0, 2));
pipeline.addLast("lengthFieldPrepender", new LengthFieldPrepender(3));
pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast(new MyClientHandler());
}
}
2.5客户端自定义Handler
public class MyClientHandler extends SimpleChannelInboundHandler<String>{
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println(ctx.channel().remoteAddress());
System.out.println(msg);
ctx.channel().writeAndFlush("to Server: 草泥马");
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println(System.currentTimeMillis() + "...........");
ctx.channel().writeAndFlush("来自于客户端的问候!");
System.out.println("client channel Active...");
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println(System.currentTimeMillis() + "...........");
System.out.println("client hanlder added...");
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println(System.currentTimeMillis() + "...........");
System.out.println("client channel register...");
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("client channel inactive...");
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("client channel unregister...");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
三. 运行测试
运行服务端启动代码,然后在运行客户端启动代码,就可以看见千万只"草泥马"在崩腾。
Netty入门之客户端与服务端通信(二)的更多相关文章
- Android BLE与终端通信(三)——客户端与服务端通信过程以及实现数据通信
Android BLE与终端通信(三)--客户端与服务端通信过程以及实现数据通信 前面的终究只是小知识点,上不了台面,也只能算是起到一个科普的作用,而同步到实际的开发上去,今天就来延续前两篇实现蓝牙主 ...
- 基于开源SuperSocket实现客户端和服务端通信项目实战
一.课程介绍 本期带给大家分享的是基于SuperSocket的项目实战,阿笨在实际工作中遇到的真实业务场景,请跟随阿笨的视角去如何实现打通B/S与C/S网络通讯,如果您对本期的<基于开源Supe ...
- Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令.
Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令. 一丶socket套接字 什么是socket套接字: 专业理解: socket是应用层与TCP/IP ...
- netty-3.客户端与服务端通信
(原) 第三篇,客户端与服务端通信 以下例子逻辑: 如果客户端连上服务端,服务端控制台就显示,XXX个客户端地址连接上线. 第一个客户端连接成功后,客户端控制台不显示信息,再有其它客户端再连接上线,则 ...
- Netty入门——客户端与服务端通信
Netty简介Netty是一个基于JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞.基于事件驱动.高性能.高可靠性和高可定制性.换句话说,Netty是一个NIO框架,使用它可以简单快速 ...
- Python socket编程客户端与服务端通信
[本文出自天外归云的博客园] 目标:实现客户端与服务端的socket通信,消息传输. 客户端 客户端代码: from socket import socket,AF_INET,SOCK_STREAM ...
- 实验09——java基于TCP实现客户端与服务端通信
TCP通信 需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手 底层通过 流 发送数据 数据没有大小限制 可靠的传输机制 - 丢包重发 包的顺序的 ...
- 二、网络编程-socket之TCP协议开发客户端和服务端通信
知识点:之前讲的udp协议传输数据是不安全的,不可靠不稳定的,tcp协议传输数据安全可靠,因为它们的通讯机制是不一样的.udp是用户数据报传输,也就是直接丢一个数据包给另外一个程序,就好比寄信给别人, ...
- mina客户端与服务端通信的易错点
使用mina进行项目开发时,如果客户端与服务端不在同一个项目下,需要关注一下两点: 第一.服务端与客户端的编码解码器一致 第二.过程中所用到的实体类的包名需要一致
随机推荐
- 10.0.0.55_12-16训练赛部分writeup
0x1 - MISC MISC100 一张帅行的照片 目测是图片隐写,但是binwalk并没有出来,应该是对文件头进行了修改 010editor查看一下,发现在jpg文件尾之后还有大量的数据 而且在灰 ...
- Android Things 专题6 完整的栗子:运用TensorFlow解析图像
文| 谷歌开发技术专家 (GDE) 王玉成 (York Wang) 前面絮叨了这么多.好像还没有一个整体的概念.我们怎样写一个完整的代码呢? 如今深度学习非常火,那我们就在Android Things ...
- 查看主机DNSserver
一.Nslookup(name server lookup)( 域名查询):是一个用于查询 Internet 域名信息或诊断DNS server问题的工具.nslookup能够指定查询的类型,能够查到 ...
- struts2 maven整合tiles3
最新项目发现使用tiles能够很好的将多个页面组合起来,以下就是配置信息,使用tiles3 1.首先配置maven pom.xml加入例如以下: <dependency> <grou ...
- 一段文字中的几个keyword显示高亮
将一段文字中的几个keyword显示高亮 演示样例:将"我的愿望是当个绿巨人,所以我想让我的皮(derma)肤是绿色"中的"皮肤"显示绿色. <span ...
- hibernate学习笔记之中的一个(JDBC回想-ORM规范)
JDBC回想-ORM规范 JDBC操作步骤 注冊数据库驱动 Class.forName("JDBCDriverClass") 数据库 驱动程序类 来源 Access sun.jdb ...
- Uva 10550 Combination Lock
Sample Input0 30 0 305 35 5 350 20 0 207 27 7 270 10 0 109 19 9 190 0 0 0Sample Output13501350162016 ...
- String、StringBuilder和StringBuffer类
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- dedecms在php7下的使用方法,织梦dedecsm后台一片空白的解决方法
前几天,一个老客户,最近升级了服务器,php到php7,把织梦dedecms转移到新服务器后,不能登录后台,让帮忙看一下. 我看了下他们的网站,使用的是织梦V57_UTF8_SP1前台页面是可以访问的 ...
- navicat创建存储过程、触发器和使用游标
创建存储过程和触发器 1.建表 首先先建两张表(users表和number表),具体设计如下图: 2.存储过程 写一个存储过程,往users表中插入数据,创建过程如下: 代码如下: BEGIN #Ro ...