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. NIO相关基础篇二

    转载请注明原创出处,谢谢! 上篇NIO相关基础篇一,主要介绍了一些基本的概念以及缓冲区(Buffer)和通道(Channel),本篇继续NIO相关话题内容,主要就是文件锁.以及比较关键的Selecto ...

  2. Hadoop 少量map/reduce任务执行慢问题

    最近在做报表统计,跑hadoop任务. 之前也跑过map/reduce但是数据量不大,遇到某些map/reduce执行时间特别长的问题. 执行时间长有几种可能性: 1. 单个map/reduce任务处 ...

  3. hdu1570(排列和组合公式的应用)

    题意: 给出字符A.则求全排列 A(n,m)=n!/(n-m)! 给出字符C.则求全组合 C(n,m)=n!/(m!*(n-m)!) http://acm.hdu.edu.cn/showproblem ...

  4. HDU_1698 Just a Hook(线段树+lazy标记)

    pid=1698">题目请点我 题解: 接触到的第一到区间更新,须要用到lazy标记.典型的区间着色问题. lazy标记详情请參考博客:http://ju.outofmemory.cn ...

  5. linux下分析Java程序内存汇总

    使用pmap查看进程内存 执行命令 使用pmap能够查看某一个进程(非java的也能够)的内存使用使用情况, 命令格式: pmap 进程id 演示样例说明 比如执行: pmap 12358 显示结果例 ...

  6. 谈谈单元測试之(二):測试工具 JUnit 3

    前言 上一篇文章<为什么要进行烦人的单元測试?>讨论了一下现阶段软件开发中,程序猿们測试情况的现状.这篇文章中,我打算介绍一下单元測试的工具(插件).而且推荐大家以后在开发中,真正的用上单 ...

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

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

  8. MAC系统里JDK版本切换

    1.首先安装需要的JDK版本 JDK7,JDK8则需要自己到Oracle官网下载安装对应的版本.自己安装的JDK默认路径为:/Library/Java/JavaVirtualMachines/jdk1 ...

  9. 关于使用Xcode9.0使用[UIImage imageNamed:]返回null的问题

    最近升级Xcode9.0,没少折腾,再加上iOS11出现的问题,又要适配一些奇怪的问题.这都没啥,但是如果Xcode出问题,那问题可真是难找.因为习惯的操作潜意思的告诉自己这样做是不会错的. 在Xco ...

  10. 【Zookeeper】源码分析目录

    Zookeeper源码分析目录如下 1. [Zookeeper]源码分析之序列化 2. [Zookeeper]源码分析之持久化(一)之FileTxnLog 3. [Zookeeper]源码分析之持久化 ...