From d3fb35e8c61b5b8ae07a1e6d2be23266c46544e4 Mon Sep 17 00:00:00 2001 From: kn5886348135 <56352848+kn5886348135@users.noreply.github.com> Date: Sat, 3 Dec 2022 16:00:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Eserver=E5=92=8Cclient?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 10 +++ .../java/com/example/tankbattle/Main.java | 12 ++-- .../com/example/tankbattle/net/Client.java | 61 +++++++++++++++++++ .../net/ClientChannelInitializer.java | 12 ++++ .../example/tankbattle/net/ClientHandler.java | 28 +++++++++ .../com/example/tankbattle/net/Server.java | 41 +++++++++++++ .../tankbattle/net/ServerChildHandler.java | 32 ++++++++++ .../example/tankbattle/net/ServerFrame.java | 51 ++++++++++++++++ .../example/tankbattle/net/TankMessage.java | 11 ++++ .../tankbattle/net/TankMessageDecoder.java | 19 ++++++ .../tankbattle/net/TankMessageEncoder.java | 14 +++++ 11 files changed, 285 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/example/tankbattle/net/Client.java create mode 100644 src/main/java/com/example/tankbattle/net/ClientChannelInitializer.java create mode 100644 src/main/java/com/example/tankbattle/net/ClientHandler.java create mode 100644 src/main/java/com/example/tankbattle/net/Server.java create mode 100644 src/main/java/com/example/tankbattle/net/ServerChildHandler.java create mode 100644 src/main/java/com/example/tankbattle/net/ServerFrame.java create mode 100644 src/main/java/com/example/tankbattle/net/TankMessage.java create mode 100644 src/main/java/com/example/tankbattle/net/TankMessageDecoder.java create mode 100644 src/main/java/com/example/tankbattle/net/TankMessageEncoder.java diff --git a/pom.xml b/pom.xml index 15ade9c..94b9137 100644 --- a/pom.xml +++ b/pom.xml @@ -33,6 +33,16 @@ spring-boot-starter-test test + + io.netty + netty-all + 4.1.76.Final + + + com.baomidou + mybatis-plus-boot-starter + 3.5.2 + diff --git a/src/main/java/com/example/tankbattle/Main.java b/src/main/java/com/example/tankbattle/Main.java index 72ac5d9..2f7d7b3 100644 --- a/src/main/java/com/example/tankbattle/Main.java +++ b/src/main/java/com/example/tankbattle/Main.java @@ -4,12 +4,12 @@ public class Main { public static void main(String[] args) throws InterruptedException { TankFrame tf = new TankFrame(); - int initTankCount = Integer.valueOf(PropertyMgr.get("initTankCount")); - - // 初始化敌方坦克 - for (int i = 0; i < initTankCount; i++) { - tf.tanks.add(new Tank(50 + i * 80, 200, Dir.DOWN, Group.BAD, tf)); - } +// int initTankCount = Integer.valueOf(PropertyMgr.get("initTankCount")); +// +// // 初始化敌方坦克 +// for (int i = 0; i < initTankCount; i++) { +// tf.tanks.add(new Tank(50 + i * 80, 200, Dir.DOWN, Group.BAD, tf)); +// } while (true) { Thread.sleep(50); diff --git a/src/main/java/com/example/tankbattle/net/Client.java b/src/main/java/com/example/tankbattle/net/Client.java new file mode 100644 index 0000000..2f382d2 --- /dev/null +++ b/src/main/java/com/example/tankbattle/net/Client.java @@ -0,0 +1,61 @@ +package com.example.tankbattle.net; + +import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; + +public class Client { + private Channel channel; + public void connect() { + EventLoopGroup group = new NioEventLoopGroup(); + Bootstrap bootstrap = new Bootstrap(); + + try { + ChannelFuture channelFuture = bootstrap.group(group).channel(NioSocketChannel.class).handler(new ClientChannelInitializer()) + .connect("localhost", 8888); + channelFuture.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + System.out.println("not conected"); + } else { + System.out.println("connected"); + channel = future.channel(); + } + } + }); + channelFuture.sync(); + channelFuture.channel().closeFuture().sync(); + System.out.println("channel closed"); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + group.shutdownGracefully(); + } + } + + public void send(String message) { + ByteBuf buf = Unpooled.copiedBuffer(message.getBytes()); + channel.writeAndFlush(buf); + } + + public static void main(String[] args) { + Client client = new Client(); + client.connect(); + client.send("hello"); + client.send("world"); + client.send("hello world"); + client.send("hello world hello"); + client.send("hello world hello world"); + } + + public void closeConnect(){ + this.send("_bye_"); + } +} diff --git a/src/main/java/com/example/tankbattle/net/ClientChannelInitializer.java b/src/main/java/com/example/tankbattle/net/ClientChannelInitializer.java new file mode 100644 index 0000000..30881d1 --- /dev/null +++ b/src/main/java/com/example/tankbattle/net/ClientChannelInitializer.java @@ -0,0 +1,12 @@ +package com.example.tankbattle.net; + +import io.netty.channel.ChannelInitializer; +import io.netty.channel.socket.SocketChannel; + +public class ClientChannelInitializer extends ChannelInitializer { + + @Override + protected void initChannel(SocketChannel socketChannel) throws Exception { + socketChannel.pipeline().addLast(new TankMessageEncoder()).addLast(new ClientHandler()); + } +} diff --git a/src/main/java/com/example/tankbattle/net/ClientHandler.java b/src/main/java/com/example/tankbattle/net/ClientHandler.java new file mode 100644 index 0000000..e56ff80 --- /dev/null +++ b/src/main/java/com/example/tankbattle/net/ClientHandler.java @@ -0,0 +1,28 @@ +package com.example.tankbattle.net; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.ReferenceCountUtil; + +public class ClientHandler extends ChannelInboundHandlerAdapter { + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ByteBuf buf = null; + try { + buf = (ByteBuf) msg; + byte[] bytes = new byte[buf.readableBytes()]; +// buf.getByte(buf.readerIndex(), bytes); + String message = new String(bytes); + } finally { + if (buf!= null) { + ReferenceCountUtil.release(buf); + } + } + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + ctx.writeAndFlush(new TankMessage(5, 8)); + } +} diff --git a/src/main/java/com/example/tankbattle/net/Server.java b/src/main/java/com/example/tankbattle/net/Server.java new file mode 100644 index 0000000..0217fea --- /dev/null +++ b/src/main/java/com/example/tankbattle/net/Server.java @@ -0,0 +1,41 @@ +package com.example.tankbattle.net; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.util.concurrent.GlobalEventExecutor; + +public class Server { + public static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); + + public void serverStart() { + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + EventLoopGroup workerGroup = new NioEventLoopGroup(2); + try { + ServerBootstrap bootstrap = new ServerBootstrap(); + ChannelFuture channelFuture = bootstrap.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline channelPipeline = ch.pipeline(); + channelPipeline.addLast(new TankMessageDecoder()).addLast(new ServerChildHandler()); + } + }).bind(8888).sync(); + + channelFuture.channel().closeFuture().sync(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + } + } +} diff --git a/src/main/java/com/example/tankbattle/net/ServerChildHandler.java b/src/main/java/com/example/tankbattle/net/ServerChildHandler.java new file mode 100644 index 0000000..602a8b0 --- /dev/null +++ b/src/main/java/com/example/tankbattle/net/ServerChildHandler.java @@ -0,0 +1,32 @@ +package com.example.tankbattle.net; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.ReferenceCountUtil; + +public class ServerChildHandler extends ChannelInboundHandlerAdapter { + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + Server.clients.add(ctx.channel()); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + System.out.println("channelRead"); + try { + System.out.println(msg.toString()); + TankMessage tankMessage = (TankMessage) msg; + System.out.println(tankMessage); + } finally { + ReferenceCountUtil.release(msg); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + Server.clients.remove(ctx.channel()); + ctx.close(); + } +} diff --git a/src/main/java/com/example/tankbattle/net/ServerFrame.java b/src/main/java/com/example/tankbattle/net/ServerFrame.java new file mode 100644 index 0000000..2591f93 --- /dev/null +++ b/src/main/java/com/example/tankbattle/net/ServerFrame.java @@ -0,0 +1,51 @@ +package com.example.tankbattle.net; + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class ServerFrame extends Frame { + public static final ServerFrame INSTANCE = new ServerFrame(); + Button btnStart = new Button("Start"); + TextArea textLeft = new TextArea(); + TextArea textRight = new TextArea(); + Server server = new Server(); + + public ServerFrame() { + this.setSize(1600, 600); + this.setLocation(300, 30); + this.add(btnStart, BorderLayout.NORTH); + Panel panel = new Panel(new GridLayout(1, 2)); + panel.add(textLeft); + panel.add(textRight); + this.add(panel); + textLeft.setFont(new Font("verderna", Font.PLAIN, 25)); + + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + } + + public static void main(String[] args) { + ServerFrame.INSTANCE.setVisible(true); + ServerFrame.INSTANCE.server.serverStart(); + } + + public void updateServerMessage(String message) { + this.textLeft.setText(textLeft.getText() + message + System.lineSeparator()); + } + + public void updateClientMessage(String message) { + this.textRight.setText(textRight.getText() + message + System.lineSeparator()); + + } +} diff --git a/src/main/java/com/example/tankbattle/net/TankMessage.java b/src/main/java/com/example/tankbattle/net/TankMessage.java new file mode 100644 index 0000000..eb87a6b --- /dev/null +++ b/src/main/java/com/example/tankbattle/net/TankMessage.java @@ -0,0 +1,11 @@ +package com.example.tankbattle.net; + +public class TankMessage { + public int x; + public int y; + + public TankMessage(int x, int y) { + this.x = x; + this.y = y; + } +} diff --git a/src/main/java/com/example/tankbattle/net/TankMessageDecoder.java b/src/main/java/com/example/tankbattle/net/TankMessageDecoder.java new file mode 100644 index 0000000..ad11e3d --- /dev/null +++ b/src/main/java/com/example/tankbattle/net/TankMessageDecoder.java @@ -0,0 +1,19 @@ +package com.example.tankbattle.net; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; + +import java.util.List; + +public class TankMessageDecoder extends ByteToMessageDecoder { + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + if (in.readableBytes() < 8) { + return; + } + int x = in.readInt(); + int y = in.readInt(); + out.add(new TankMessage(x, y)); + } +} diff --git a/src/main/java/com/example/tankbattle/net/TankMessageEncoder.java b/src/main/java/com/example/tankbattle/net/TankMessageEncoder.java new file mode 100644 index 0000000..cb35540 --- /dev/null +++ b/src/main/java/com/example/tankbattle/net/TankMessageEncoder.java @@ -0,0 +1,14 @@ +package com.example.tankbattle.net; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +public class TankMessageEncoder extends MessageToByteEncoder { + + @Override + protected void encode(ChannelHandlerContext ctx, TankMessage msg, ByteBuf out) throws Exception { + out.writeInt(msg.x); + out.writeInt(msg.y); + } +}