1.创建Maven工程

1.1 父节点的pom.xml代码(root pom文件)

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7 <groupId>org.example</groupId>
8 <artifactId>echo_netty</artifactId>
9 <packaging>pom</packaging>
10 <version>1.0-SNAPSHOT</version>
11 <modules>
12 <module>netty-server</module>
13 <module>netty-client</module>
14 </modules>
15
16 </project>

1.2 子工程netty-server的pom.xml文件代码

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <parent>
6 <artifactId>echo_netty</artifactId>
7 <groupId>org.example</groupId>
8 <version>1.0-SNAPSHOT</version>
9 </parent>
10 <modelVersion>4.0.0</modelVersion>
11
12 <artifactId>netty-server</artifactId>
13
14
15 </project>

1.3 子工程netty-client的pom.xml文件代码

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <parent>
6 <artifactId>echo_netty</artifactId>
7 <groupId>org.example</groupId>
8 <version>1.0-SNAPSHOT</version>
9 </parent>
10 <modelVersion>4.0.0</modelVersion>
11
12 <artifactId>netty-client</artifactId>
13
14
15 </project>

1.4 修改父工程的pom.xml,修改后如下所示:

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7 <groupId>org.example</groupId>
8 <artifactId>echo_netty</artifactId>
9 <packaging>pom</packaging>
10 <version>1.0-SNAPSHOT</version>
11 <modules>
12 <module>netty-server</module>
13 <module>netty-client</module>
14 </modules>
15
16 <properties>
17 <echo-server.hostname>localhost</echo-server.hostname>
18 <echo-server.port>9999</echo-server.port>
19 </properties>
20
21 <dependencies>
22 <dependency>
23 <groupId>io.netty</groupId>
24 <artifactId>netty-all</artifactId>
25 <version>4.1.10.Final</version>
26 <scope>compile</scope>
27 </dependency>
28 </dependencies>
29
30 <build>
31 <plugins>
32 <plugin>
33 <artifactId>maven-compiler-plugin</artifactId>
34 </plugin>
35 <plugin>
36 <artifactId>maven-failsafe-plugin</artifactId>
37 </plugin>
38 <plugin>
39 <artifactId>maven-surefire-plugin</artifactId>
40 </plugin>
41 <plugin>
42 <groupId>org.codehaus.mojo</groupId>
43 <artifactId>exec-maven-plugin</artifactId>
44 </plugin>
45 </plugins>
46 </build>
47 </project>

1.5 修改netty-server的pom.xml,修改后如下所示:

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <parent>
6 <artifactId>echo_netty</artifactId>
7 <groupId>org.example</groupId>
8 <version>1.0-SNAPSHOT</version>
9 </parent>
10 <modelVersion>4.0.0</modelVersion>
11
12 <artifactId>netty-server</artifactId>
13
14 <build>
15 <plugins>
16 <plugin>
17 <groupId>org.codehaus.mojo</groupId>
18 <artifactId>exec-maven-plugin</artifactId>
19 <executions>
20 <execution>
21 <id>run-server</id>
22 <goals>
23 <goal>java</goal>
24 </goals>
25 </execution>
26 </executions>
27 <configuration>
28 <mainClass>com.echo.server.EchoServer</mainClass>
29 <arguments>
30 <argument>${echo-server.port}</argument>
31 </arguments>
32 </configuration>
33 </plugin>
34 </plugins>
35 </build>
36
37 </project>

1.6 修改netty-client的pom.xml,修改后如下所示:

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <parent>
6 <artifactId>echo_netty</artifactId>
7 <groupId>org.example</groupId>
8 <version>1.0-SNAPSHOT</version>
9 </parent>
10 <modelVersion>4.0.0</modelVersion>
11
12 <artifactId>netty-client</artifactId>
13
14 <build>
15 <plugins>
16 <plugin>
17 <groupId>org.codehaus.mojo</groupId>
18 <artifactId>exec-maven-plugin</artifactId>
19 <executions>
20 <execution>
21 <id>run-server</id>
22 <goals>
23 <goal>java</goal>
24 </goals>
25 </execution>
26 </executions>
27 <configuration>
28 <mainClass>com.echo.client.EchoClient</mainClass>
29 <arguments>
30 <argument>${echo-server.hostname}</argument>
31 <argument>${echo-server.port}</argument>
32 </arguments>
33 </configuration>
34 </plugin>
35 </plugins>
36 </build>
37
38 </project>

2. 开始写netty客户端的代码

到这里的时候,项目的结构应该是这个样子的,然后让我们修改一下EchoClient.java和EchoClientHandler.java文件的内容,修改后最终代码放在下面,大家请看:

2.1 EchoClient.java的最终代码

 1 package com.echo.client;
2
3 import java.net.InetSocketAddress;
4
5 import com.echo.client.handler.EchoClientHandler;
6 import io.netty.bootstrap.Bootstrap;
7 import io.netty.channel.ChannelFuture;
8 import io.netty.channel.ChannelInitializer;
9 import io.netty.channel.EventLoopGroup;
10 import io.netty.channel.nio.NioEventLoopGroup;
11 import io.netty.channel.socket.SocketChannel;
12 import io.netty.channel.socket.nio.NioSocketChannel;
13
14 public class EchoClient {
15
16 private final String host;
17 private final int port;
18
19 public EchoClient(String host, int port) {
20 this.host = host;
21 this.port = port;
22 }
23
24 public static void main(String[] args) throws Exception {
25 if (args.length != 2) {
26 System.err.println(
27 "Usage: " + EchoClient.class.getSimpleName() +
28 " <host> <port>");
29 return;
30 }
31 String host = args[0];
32 int port = Integer.parseInt(args[1]);
33 new EchoClient(host, port).start();
34 }
35
36 public void start() throws Exception {
37 EventLoopGroup group = new NioEventLoopGroup();
38 try {
39 Bootstrap b = new Bootstrap();
40 b.group(group)
41 .channel(NioSocketChannel.class)
42 .remoteAddress(new InetSocketAddress(host, port))
43 .handler(new ChannelInitializer<SocketChannel>() {
44
45 @Override
46 protected void initChannel(SocketChannel ch) throws Exception {
47 ch.pipeline().addLast(new EchoClientHandler());
48 }
49
50 });
51 ChannelFuture f = b.connect().sync();
52 f.channel().closeFuture().sync();
53 } finally {
54 group.shutdownGracefully().sync();
55 }
56 }
57
58 }

2.2 EchoClientHandler.java的最终代码

 1 package com.echo.client.handler;
2
3 import io.netty.buffer.ByteBuf;
4 import io.netty.buffer.Unpooled;
5 import io.netty.channel.ChannelHandler.Sharable;
6 import io.netty.channel.ChannelHandlerContext;
7 import io.netty.channel.SimpleChannelInboundHandler;
8 import io.netty.util.CharsetUtil;
9
10 @Sharable
11 public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
12
13 @Override
14 public void channelActive(ChannelHandlerContext ctx) throws Exception {
15 ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8));
16 }
17
18 @Override
19 protected void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
20 System.out.println("Client received: " + in.toString(CharsetUtil.UTF_8));
21 }
22
23 @Override
24 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
25 cause.printStackTrace();
26 ctx.close();
27 }
28
29 }

到这的时候,如果有报错的话,一般是maven没有刷新导致的。

解决方法是,打开父工程的pom.xml ,然后点击idea的右侧的maven刷新按钮,如下图所示

至此,EchoClient端的代码就写好了。暂时先不启动,先写好EchoServer,再一起启动。下面介绍EchoServer端的代码。

3. 开始写netty服务端的代码

3.2 修改EchoServer.java文件代码,修改后最终代码如下:

 1 package com.echo.server;
2
3 import java.net.InetSocketAddress;
4
5 import com.echo.server.handler.EchoServerHandler;
6 import io.netty.bootstrap.ServerBootstrap;
7 import io.netty.channel.ChannelFuture;
8 import io.netty.channel.ChannelInitializer;
9 import io.netty.channel.EventLoopGroup;
10 import io.netty.channel.nio.NioEventLoopGroup;
11 import io.netty.channel.socket.SocketChannel;
12 import io.netty.channel.socket.nio.NioServerSocketChannel;
13
14 public class EchoServer {
15
16 private final int port;
17
18 public EchoServer(int port) {
19 this.port = port;
20 }
21
22 public void start() throws Exception {
23 final EchoServerHandler serverHandler = new EchoServerHandler();
24 EventLoopGroup group = new NioEventLoopGroup();
25 try {
26 ServerBootstrap b = new ServerBootstrap();
27 b.group(group)
28 .channel(NioServerSocketChannel.class)
29 .localAddress(new InetSocketAddress(port))
30 .childHandler(new ChannelInitializer<SocketChannel>() {
31
32 @Override
33 protected void initChannel(SocketChannel ch) throws Exception {
34 ch.pipeline().addLast(serverHandler);
35 }
36 });
37 // 此处绑定服务器,并等待绑定完成。对sync()方法的调用将导致当前Thread阻塞,直到绑定完成
38 ChannelFuture f = b.bind().sync();
39 // 由于调用了sync()方法,程序将会阻塞等待,直到服务器的Channel关闭
40 f.channel().closeFuture().sync();
41 } finally {
42 group.shutdownGracefully().sync();
43 }
44 }
45
46 public static void main(String[] args) throws Exception {
47 if (args.length != 1) {
48 System.err.println(
49 "Usage: " + EchoServer.class.getSimpleName() + " <port>"
50 );
51 return;
52 }
53 int port = Integer.parseInt(args[0]);
54 new EchoServer(port).start();
55 }
56
57 }

3.3 修改EchoServerHandler.java文件代码,修改后最终代码如下:

 1 package com.echo.server.handler;
2
3 import io.netty.buffer.ByteBuf;
4 import io.netty.buffer.Unpooled;
5 import io.netty.channel.ChannelHandler.Sharable;
6 import io.netty.channel.ChannelFutureListener;
7 import io.netty.channel.ChannelHandlerContext;
8 import io.netty.channel.ChannelInboundHandlerAdapter;
9 import io.netty.util.CharsetUtil;
10
11 // @Sharable标示一个ChannelHandler可以被多个Channel安全共享
12 @Sharable
13 public class EchoServerHandler extends ChannelInboundHandlerAdapter {
14
15 @Override
16 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
17 ByteBuf in = (ByteBuf) msg;
18 System.out.println(
19 "Server received: " + in.toString(CharsetUtil.UTF_8));
20 // 将接收到的消息写给发送者,即客户端,而不冲刷出站消息
21 ctx.write(in);
22 }
23
24 @Override
25 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
26 // 将未决消息冲刷到远程节点,并且关闭该Channel
27 ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
28 .addListener(ChannelFutureListener.CLOSE);
29 }
30
31 @Override
32 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
33 cause.printStackTrace();
34 ctx.close();
35 }
36
37 }

至此,所有的代码已经写好,下一步进行运行测试

4.运行代码

4.1 打包代码

当出现BUILD SUCCESS的时候,代表代码已经打包好了。

4.2 运行server端

出现一直在转圈的时候,代表server端启动成功了

4.3 运行client端

双击运行client端,然后稍等片刻,会发现下图已经出现了

Client received: Netty rocks!

这一行字。说明客户端和服务端通信成功。

接着看一下server端打印的输出,如下图:

可以看到,server端已经输出了从客户端收到的消息!!!

至此,所有的演示都结束了,大家自己动手进行实践吧。

netty写Echo Server & Client完整步骤教程(图文)的更多相关文章

  1. Simple TCP/IP Echo Server & Client Application in C#

    1. TCP Server The server’s job is to set up an endpoint for clients to connect to and passively wait ...

  2. mac下安装MySQL完整步骤(图文详情)

    原文摘自:http://www.jb51.net/article/103841.htm 最近使用Mac系统,准备搭建一套本地web服务器环境.因为Mac系统自带PHP和apach,但是没有自带mysq ...

  3. [z]libevent入门教程:Echo Server based on libevent 不指定

    [z]https://www.felix021.com/blog/read.php?2068 花了两天的时间在libevent上,想总结下,就以写简单tutorial的方式吧,貌似没有一篇简单的说明, ...

  4. libevent 入门教程:Echo Server based on libevent(转)

    下面假定已经学习过基本的socket编程(socket, bind, listen, accept, connect, recv, send, close),并且对异步/callback有基本的认识. ...

  5. 《连载 | 物联网框架ServerSuperIO教程》- 16.OPC Server的使用步骤。附:3.3 发布与版本更新说明。

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  6. BI之SSAS完整实战教程2 -- 开发环境介绍及多维数据集数据源准备

    上一篇我们已经完成所有的准备工作,现在我们就开始动手,通过接下来的三篇文章创建第一个多维数据集. 传统的维度和多维数据集设计方法主要是基于现有的单源数据集. 在现实世界中,当开发商业智能应用程序时,很 ...

  7. 安装node.js 和 npm 的完整步骤

    vue 生命周期 1,beforeCreate 组件刚刚被创建 2,created 组件创建完成 3,beforeMount 挂载之前 4,mounted 挂载之后 5,beforeDestory 组 ...

  8. BI之SSAS完整实战教程7 -- 设计维度、细化维度中 :浏览维度,细化维度

    上篇文章我们已经将Dim Geography维度设计好. 若要查看维度的成员, AS需要接收该维度的详细信息(包括已创建的特性.成员属性以及多级层次结构), 通过XMLA与AS的实例进行通信. 今天我 ...

  9. BI之SSAS完整实战教程1 -- 开篇, BI简介 & SSAS简介

    文章提纲 商业智能(BI, Business Intelligence)基本概念 SSAS(SQL Server Analysis Services)相关工具(开发.管理和客户端) 总结 一.商业智能 ...

随机推荐

  1. Hbase-cdh5.14.2与kylin集成异常

    1.原先使用版本:apache-kylin-2.5.1-bin-hbase1x 原生版本 启动报错出现异常: Failed to find metadata store by url: kylin_m ...

  2. 建立索引和创建视图(结合YGGL.sql)

    一.请按要求对YGGL库建立相关索引 (1)使用create index 语句创建索引 1.对employees表中的员工部门号创建普通索引depart_ind. mysql> create i ...

  3. Apache下的配置文件httpd.conf、httpd-vhosts.conf 转

    Apache下的配置文件httpd.conf.httpd-vhosts.conf(windows) 2013-05-24 22:09 by youxin, 58 阅读, 0 评论, 收藏, 编辑 ht ...

  4. 杭电2734----Quicksum(C++)(数字与字符的关系)

    Quicksum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  5. 一图看懂Actor Typed

    引言 朋友看罢我之前整理的<Akka Typed 官方文档之随手记>,一人用了诗歌<长城长>作为回赠,另一人则要求推出简化版本.于是抽空整理了几张思维导图,并且用了一些不太恰当 ...

  6. react项目中实现搜索关键字呈现高亮状态(一)

    最近有个需求,在一个react项目中,实现搜索关键字呈现高亮状态.这个在普通的html文件中还好操作些,在react项目中有点懵逼了,因为react项目中很少操作dom,有点无从下手.但最后还是实现了 ...

  7. 【Flutter】布局类组件之对齐和相对定位

    前言 如果只想简单的调整一个子元素在父元素中的位置的话,使用Align组件会更简单一些. 接口描述 const Align({ Key key, // 需要一个AlignmentGeometry类型的 ...

  8. LeetCode220 存在重复元素 III

    给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. 示例 1: 输入: ...

  9. python模块详解 | shutil

    简介: shutil是python的一个内置模块,提供了许多关于文件和文件集合的高级操作,特别提供文件夹与文件操作.归档操作了支持文件复制和删除的功能. 文件夹与文件操作: copyfileobj(f ...

  10. 【Linux】dd命令进行磁盘备份

    运用dd命令,将/dev/sdb磁盘中所有的数据全部备份到/dev/sdc磁盘上,需要的命令如下 dd  if=/dev/sdb of=/dev/sdc bs=1024k 说明,if是需要备份的磁盘  ...