总体来说只需要三个步骤,下面详细介绍
第一步 创建SpringBoot工程snetty
Client
,Server
,均为SpringBoot工程第三步 将服务器端和客户端的代码分别打成Jar包,运行Jar包。因为Netty
需要客户端与服务器端两个端口才能看到效果,但是IDE的console只有一个窗口,所以需要将两个端口代码分别打成Jar包,这样再运行的话,就有两个窗口了。 先说一下遇到的问题,具体代码在下边。 打包运行
因为我运行Jar包使用的是mvn exec:java
这个命令,是将主函数main
的参数构建在pom.xml
文件中。
org.codehaus.mojo exec-maven-plugin 1.2.1 run-server java com.bihang.server.server2.EchoServer ${echo-server.port}
也就是说当我用mvn clean package
这个命令将服务器端的代码打成Jar包之后,再运行mvn exec:java
命令,此时服务器端就启动了。
<mainClass>com.bihang.server.server2.EchoServer</mainClass>
这里放的就是主函数。 ${echo-server.port}
这里放的是主函数的参数。
获取父级pom.xml的信息
${echo-server.port}
这个值是从父级pom.xml
中的properties
中获取的,很关键的就是,在子模块Server
的pom.xml中的<parent>
标签中要这么写才能获得父级pom.xml
中的信息。
com.bihang snetty 0.0.1-SNAPSHOT ../pom.xml
父级中的properties
:
1.8 127.0.0.1 8888
并且父级中的<packaging>
标签要改成pom
形式
pom
具体代码
引入依赖
io.netty netty-all 4.0.36.Final log4j log4j 1.2.17
服务器端和客户端都只需要两部分代码,一个是处理器程序,一个是引导程序。
服务器端的EchoServerHandler
import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.util.CharsetUtil;@ChannelHandler.Sharablepublic class EchoServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf in = (ByteBuf) msg; System.out.println( "Server received: " + in.toString(CharsetUtil.UTF_8)); ctx.write(in); } @Override public void channelReadComplete(ChannelHandlerContext ctx) { ctx.writeAndFlush(Unpooled.EMPTY_BUFFER) .addListener(ChannelFutureListener.CLOSE); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); }}
服务器端的EchoServer
import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;import java.net.InetSocketAddress;public class EchoServer { private final int port; public EchoServer(int port) { this.port = port; } public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println( "Usage: " + EchoServer.class.getSimpleName() + ""); } int port = Integer.parseInt(args[0]); new EchoServer(port).start(); } public void start() throws Exception { final EchoServerHandler serverHandler = new EchoServerHandler(); EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(group) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(port)) .childHandler(new ChannelInitializer () { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(serverHandler); } }); ChannelFuture f = b.bind().sync(); f.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } }}
客户端的EchoClientHandler
import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.util.CharsetUtil;public class EchoClientHandler extends SimpleChannelInboundHandler{ //在到服务器的连接已经建立之后将被调用 @Override public void channelActive(ChannelHandlerContext ctx) { ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8)); } //当从服务器接收到一条消息时被调用 @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf in) throws Exception { System.out.println( "Client received: " + in.toString(CharsetUtil.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); }}
客户端的EchoClient
import io.netty.bootstrap.Bootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioSocketChannel;import java.net.InetSocketAddress;public class EchoClient { private final String host; private final int port; public EchoClient(String host, int port) { this.host = host; this.port = port; } public void start() throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .remoteAddress(new InetSocketAddress(host, port)) .handler(new ChannelInitializer() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast( new EchoClientHandler()); } }); ChannelFuture f = b.connect().sync(); f.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } } public static void main(String[] args) throws Exception { if (args.length != 2) { System.err.println( "Usage: " + EchoClient.class.getSimpleName() + " "); return; } String host = args[0]; int port = Integer.parseInt(args[1]); new EchoClient(host, port).start(); }}