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入门之客户端与服务端通信(二)的更多相关文章

  1. Android BLE与终端通信(三)——客户端与服务端通信过程以及实现数据通信

    Android BLE与终端通信(三)--客户端与服务端通信过程以及实现数据通信 前面的终究只是小知识点,上不了台面,也只能算是起到一个科普的作用,而同步到实际的开发上去,今天就来延续前两篇实现蓝牙主 ...

  2. 基于开源SuperSocket实现客户端和服务端通信项目实战

    一.课程介绍 本期带给大家分享的是基于SuperSocket的项目实战,阿笨在实际工作中遇到的真实业务场景,请跟随阿笨的视角去如何实现打通B/S与C/S网络通讯,如果您对本期的<基于开源Supe ...

  3. Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令.

    Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令. 一丶socket套接字 什么是socket套接字: ​ ​  ​ 专业理解: socket是应用层与TCP/IP ...

  4. netty-3.客户端与服务端通信

    (原) 第三篇,客户端与服务端通信 以下例子逻辑: 如果客户端连上服务端,服务端控制台就显示,XXX个客户端地址连接上线. 第一个客户端连接成功后,客户端控制台不显示信息,再有其它客户端再连接上线,则 ...

  5. Netty入门——客户端与服务端通信

    Netty简介Netty是一个基于JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞.基于事件驱动.高性能.高可靠性和高可定制性.换句话说,Netty是一个NIO框架,使用它可以简单快速 ...

  6. Python socket编程客户端与服务端通信

    [本文出自天外归云的博客园] 目标:实现客户端与服务端的socket通信,消息传输. 客户端 客户端代码: from socket import socket,AF_INET,SOCK_STREAM ...

  7. 实验09——java基于TCP实现客户端与服务端通信

    TCP通信         需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手        底层通过 流 发送数据 数据没有大小限制        可靠的传输机制 - 丢包重发 包的顺序的 ...

  8. 二、网络编程-socket之TCP协议开发客户端和服务端通信

    知识点:之前讲的udp协议传输数据是不安全的,不可靠不稳定的,tcp协议传输数据安全可靠,因为它们的通讯机制是不一样的.udp是用户数据报传输,也就是直接丢一个数据包给另外一个程序,就好比寄信给别人, ...

  9. mina客户端与服务端通信的易错点

    使用mina进行项目开发时,如果客户端与服务端不在同一个项目下,需要关注一下两点: 第一.服务端与客户端的编码解码器一致 第二.过程中所用到的实体类的包名需要一致

随机推荐

  1. oracle和mysql几点差异对比

    Oracle与mysql差异性总结 之前有个项目是用oracle数据库进行开发,需要把数据库改成mysql,遇到了一些地方需要注意的,就简单记了下来. 备注: 再把oracle转成mysql的时候,表 ...

  2. 调参过程中的参数 学习率,权重衰减,冲量(learning_rate , weight_decay , momentum)

    无论是深度学习还是机器学习,大多情况下训练中都会遇到这几个参数,今天依据我自己的理解具体的总结一下,可能会存在错误,还请指正. learning_rate , weight_decay , momen ...

  3. msf入门学习笔记

    msf-------------------------------------- service postgresql startservice metasploit startmsfconsole ...

  4. SQL基础教程读书笔记-1

    查询基础 2.2 算数运算符和比较运算符 2.2.1算数运算符 + - * / 需要注意NULL 5 + NULL 10 - NULL 1 * NULL 4 / NULL NULL / 9 NULL ...

  5. 框架原理第一讲,熟悉常用的设计方式.(以MFC框架讲解)

    框架原理第一讲,熟悉常用的设计方式.(以MFC框架讲解) 一丶什么是框架,以及框架的作用 什么是框架? 框架,简而言之就是把东西封装好了,使用框架开发可以快速开发程序,例如MFC程序的双击写代码. 为 ...

  6. Struts2学习笔记整理(一)

    最近在学习框架,很多人建议我直接学SSM,SSM看了一段时间后发现很多东西虽然可以用了,但是并不是很了解,所以我打算重新来过.从SSH开始学习,前面已经大致的学习了Hibernate,对于Hibern ...

  7. VMware---添加esxi主机的实验

     实验环境:window_server_2012_r2_64 SQLServer2012SP1-FullSlipstream-CHS-x64 虚机配置: 关于windows server2012 和 ...

  8. Git(一)之基本操作详解

    前言 在这段时间的工作中一直都是用Git作为版本控制,只是知道简单的几个命令,没有去了解它的内部原理.所以周末有时间来系统学习. 现在的公司基本上都是用Git作为版本控制,当然也有SVN的. Git是 ...

  9. 在Visual Studio 中开发Office Add-in

    作者:陈希章 发表于2017年7月13日 "Talk is cheap, show me the code",我们就用代码来说话吧.这一篇将给大家介绍如何开始Office Add- ...

  10. 三、spring cloud 服务提供与调用

    如何使用eureka服务注册中心,搭建一个简单的服务端注册服务,客户端去调用服务使用. 案例中有三个角色:服务注册中心.服务提供者.服务消费者,eureka单机版启动既可,流程是首先启动注册中心,服务 ...