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. 【Struts2的执行流程,这个博主写的很详细】

    http://blog.csdn.net/wjw0130/article/details/46371847

  2. Ubuntu下deb包的解压、打包、安装、卸载及常用命令参数

    1.首先下载deb包,比如:将其放在 /home/tools/ 根目录下: 2.进入到tools根目录下的终端,输入下面命令创建文件夹extract,并在extract文件夹下创建DEBIAN文件夹 ...

  3. 零基础学python-2.8 字典

    字典类型,事实上就是相当于java的map,通过key-value来记录数据,工作原理类似于哈希表 差点儿全部的python对象都能够作为key,可是一般最经常使用的还是数字和字符串 字典元素使用{} ...

  4. HTML学习笔记之三(localstorage的使用)

    localstorage的使用 1.获取对象 var localstroage = window.localStorage; 2.存储值 localstroage.setItem('openid',' ...

  5. Struts2报错org.apache.jasper.JasperException: Invalid directive原因

    struts标签书写错误.<s:textfield name="us.username"/>对的<s:textfield name="us.userna ...

  6. JQuery插件开发标准写法

    ;//step01 定义JQuery的作用域 (function ($) { //step03-a 插件的默认值属性 var defaults = { prevId: 'prevBtn', prevT ...

  7. vue中使用keepAlive组件缓存遇到的坑

    项目开发中在用户由分类页category进入detail需保存用户状态,查阅了Vue官网后,发现vue2.0提供了一个keep-alive组件. 上一篇讲了keep-alive的基本用法,现在说说遇到 ...

  8. SpringCloud四:hystrix-propagation

    注:pom.xml 及配置文件配置与上篇相同 package com.itmuch.cloud.controller; import org.springframework.beans.factory ...

  9. 微信小程序路过

    应该算是入门篇, 从我怎么0基础然后沿着什么方向走,遇到的什么坑,如何方向解决,不过本人接触不是很多,所以也就了解有限. 小程序的前提: 1.小程序大小不允许超过2M.(也就是本地图片,大图精图不要在 ...

  10. SLAM入门之视觉里程计(2):相机模型(内参数,外参数)

    相机成像的过程实际是将真实的三维空间中的三维点映射到成像平面(二维空间)过程,可以简单的使用小孔成像模型来描述该过程,以了解成像过程中三维空间到二位图像空间的变换过程. 本文包含两部分内容,首先介绍小 ...