基於socket的netty demo

前面一文說了 基於http的netty demojava

和http不同,http能夠用瀏覽器來充當客戶端調用,因此基於socket的netty,必需要編寫客戶端和服務器的代碼bootstrap

 

實現功能:
客戶端給服務器發消息,服務器給客戶端回消息
一直循環瀏覽器

服務器代碼

 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 }

 

執行結果

先運行服務器:服務器

再運行客戶端:dom

運行完客戶端後服務器的狀況socket

 

完整代碼下載:ide

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

相關文章
相關標籤/搜索