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. 数仓面试高频考点--解决hive小文件过多问题

    本文首发于公众号:五分钟学大数据 小文件产生原因 hive 中的小文件肯定是向 hive 表中导入数据时产生,所以先看下向 hive 中导入数据的几种方式 直接向表中插入数据 insert into ...

  2. Databricks 第四篇:分组统计和窗口

    对数据分析时,通常需要对数据进行分组,并对每个分组进行聚合运算.在一定意义上,窗口也是一种分组统计的方法. 分组数据 DataFrame.groupBy()返回的是GroupedData类,可以对分组 ...

  3. 借助window.performance实现基本的前端基础性能监控日志

    借助window.performance实现基本的前端基础性能监控日志并二次重写console方法方便日常前端console日志的调试 npm install sn-console

  4. Windows Server 2012 R2远程桌面默认端口修改

    修改3389默认端口可使服务器安全性进一步提升,可以避免阻断大部分的恶意暴力密码爆破. 在开始--运行菜单里,输入regedit 或者: 远程登陆服务器选择系统桌面中的"Windows Po ...

  5. 洛谷P3275 [SCOI2011]糖果(差分约束)

    题目描述 幼儿园里有 $N$ 个小朋友,$lxhgww $老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的 ...

  6. PAT练习num3-跟奥巴马一起学编程

    美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统.2014 年底,为庆祝"计算机科学教育周"正式启动,奥巴马编写了很简单的计算机 ...

  7. 学习Java第一天

    public 保证类名和文件名一致 关键字字母全小写,编辑器中有颜色标记 null空常量不能打印 变量就是内存中的存储空间 计算机中最小的存储单元时字节(byte) //1字节(B) = 8位(bit ...

  8. 不用git 手动对比文件差异

    使用python脚本比较两个文件的差异内容并输出到html文档中,可以通过浏览器打开查看. 一.脚本使用 对比文件的差异 python python_diff_file.py -f1 web26.co ...

  9. uni-app 微信小程序 picker 三级联动

    之前做过一个picker的三级联动功能,这里分享代码给大家 具体代码: // An highlighted block <template> <view> <picker ...

  10. SUGA

    愿试炼的终点是花开万里 愿以渺小启程伟大结束 ----闵玧其