基于socket的netty demo

前面一文说了 基于http的netty demo

和http不一样,http可以用浏览器来充当客户端调用,所以基于socket的netty,必须要编写客户端和服务器的代码

 

实现功能:
客户端给服务器发消息,服务器给客户端回消息
一直循环

服务器代码

 1 package com.bill.socketdemo;
 2 
 3 
 4 import io.netty.bootstrap.ServerBootstrap;
 5 import io.netty.channel.ChannelFuture;
 6 import io.netty.channel.EventLoopGroup;
 7 import io.netty.channel.nio.NioEventLoopGroup;
 8 import io.netty.channel.socket.nio.NioServerSocketChannel;
 9 
10 public class SocketServer {
11 
12     public static void main(String[] args) throws Exception {
13 
14         // 这2个group都是死循环,阻塞式
15         EventLoopGroup bossGroup = new NioEventLoopGroup();
16         EventLoopGroup workerGroup = new NioEventLoopGroup();
17 
18         try {
19             ServerBootstrap serverBootstrap = new ServerBootstrap();
20             serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).
21                     childHandler(new SocketServerInitializer());
22 
23             ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
24             channelFuture.channel().closeFuture().sync();
25         } finally {
26             bossGroup.shutdownGracefully();
27             workerGroup.shutdownGracefully();
28         }
29     }
30 
31 }
32 
33 package com.bill.socketdemo;
34 
35 import io.netty.channel.ChannelHandlerContext;
36 import io.netty.channel.SimpleChannelInboundHandler;
37 
38 import java.util.UUID;
39 
40 public class SocketServerHandler extends SimpleChannelInboundHandler<String> {
41 
42     /**
43      * 读取客户端请求,并且返回给客户端数据的方法
44      */
45     @Override
46     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
47         System.out.println(ctx.channel().remoteAddress() + ", " + msg);
48         ctx.channel().writeAndFlush("from server:" + UUID.randomUUID());
49     }
50 
51     /**
52      * 处理异常的方法,一旦出现异常,就会调用此方法
53      */
54     @Override
55     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
56         cause.printStackTrace();
57         ctx.close();
58     }
59 }
60 
61 package com.bill.socketdemo;
62 
63 import io.netty.channel.ChannelInitializer;
64 import io.netty.channel.ChannelPipeline;
65 import io.netty.channel.socket.SocketChannel;
66 import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
67 import io.netty.handler.codec.LengthFieldPrepender;
68 import io.netty.handler.codec.string.StringDecoder;
69 import io.netty.handler.codec.string.StringEncoder;
70 import io.netty.util.CharsetUtil;
71 
72 public class SocketServerInitializer extends ChannelInitializer<SocketChannel> {
73 
74     @Override
75     protected void initChannel(SocketChannel socketChannel) throws Exception {
76 
77         ChannelPipeline pipeline = socketChannel.pipeline();
78 
79         pipeline.addLast("LengthFieldBasedFrameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
80         pipeline.addLast("LengthFieldPrepender",new LengthFieldPrepender(4));
81         pipeline.addLast("StringDecoder",new StringDecoder(CharsetUtil.UTF_8));
82         pipeline.addLast("StringEncoder",new StringEncoder(CharsetUtil.UTF_8));
83         pipeline.addLast("SocketServerHandler", new SocketServerHandler());
84     }
85 }

 

客户端代码

 1 package com.bill.socketdemo;
 2 
 3 
 4 import io.netty.bootstrap.Bootstrap;
 5 import io.netty.channel.ChannelFuture;
 6 import io.netty.channel.EventLoopGroup;
 7 import io.netty.channel.nio.NioEventLoopGroup;
 8 import io.netty.channel.socket.nio.NioSocketChannel;
 9 
10 public class SocketClient {
11 
12     public static void main(String[] args) throws Exception {
13 
14         // 这2个group都是死循环,阻塞式
15         EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
16 
17         try {
18             Bootstrap bootstrap = new Bootstrap();
19             bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).
20                     handler(new SocketClientInitializer());
21 
22             ChannelFuture channelFuture = bootstrap.connect("localhost", 8899).sync();
23             channelFuture.channel().closeFuture().sync();
24         } finally {
25             eventLoopGroup.shutdownGracefully();
26         }
27     }
28 
29 }
30 
31 package com.bill.socketdemo;
32 
33 import io.netty.channel.ChannelHandlerContext;
34 import io.netty.channel.SimpleChannelInboundHandler;
35 
36 import java.util.UUID;
37 
38 public class SocketClientHandler extends SimpleChannelInboundHandler<String> {
39 
40     /**
41      * 发送内容给服务器端
42      */
43     @Override
44     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
45         System.out.println(ctx.channel().remoteAddress());
46         System.out.println("client output:" + msg);
47         ctx.writeAndFlush("from client:" + UUID.randomUUID());
48     }
49 
50     /**
51      * 该方法向服务器发数据,打破服务器-客户端一直等待对方发数据的僵局
52      */
53     @Override
54     public void channelActive(ChannelHandlerContext ctx) throws Exception {
55         ctx.writeAndFlush("from client: hello world");
56     }
57 
58     /**
59      * 处理异常的方法,一旦出现异常,就会调用此方法
60      */
61     @Override
62     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
63         cause.printStackTrace();
64         ctx.close();
65     }
66 }
67 
68 package com.bill.socketdemo;
69 
70 import io.netty.channel.ChannelInitializer;
71 import io.netty.channel.ChannelPipeline;
72 import io.netty.channel.socket.SocketChannel;
73 import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
74 import io.netty.handler.codec.LengthFieldPrepender;
75 import io.netty.handler.codec.string.StringDecoder;
76 import io.netty.handler.codec.string.StringEncoder;
77 import io.netty.util.CharsetUtil;
78 
79 public class SocketClientInitializer extends ChannelInitializer<SocketChannel> {
80 
81     @Override
82     protected void initChannel(SocketChannel socketChannel) throws Exception {
83 
84         ChannelPipeline pipeline = socketChannel.pipeline();
85 
86         pipeline.addLast("LengthFieldBasedFrameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
87         pipeline.addLast("LengthFieldPrepender",new LengthFieldPrepender(4));
88         pipeline.addLast("StringDecoder",new StringDecoder(CharsetUtil.UTF_8));
89         pipeline.addLast("StringEncoder",new StringEncoder(CharsetUtil.UTF_8));
90         pipeline.addLast("SocketServerHandler", new SocketClientHandler());
91     }
92 }

 

执行结果

先运行服务器:

再运行客户端:

运行完客户端后服务器的情况

 

完整代码下载:

https://download.csdn.net/download/mweibiao/10551574

 

posted @ 2018-07-19 17:23  无名草110  阅读(861)  评论(0编辑  收藏  举报