Netty4服务端和客户端实现
生活随笔
收集整理的這篇文章主要介紹了
Netty4服务端和客户端实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
目標
代碼UML類圖
服務端
客戶端
Netty4實現服務端
Netty4實現客戶端
測試
小結
目標
用netty4實現一個服務端和客戶端,兩者之間可以進行測試通信
代碼UML類圖
服務端
客戶端
Netty4實現服務端
服務類
package com.mym.netty.server;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder;/*** netty服務端*/ public class NettyServer {public static void main(String[] args) {startServer();}public static void startServer(){//1.定義server啟動類ServerBootstrap serverBootstrap = new ServerBootstrap();//2.定義工作組:boss分發請求給各個worker:boss負責監聽端口請求,worker負責處理請求(讀寫)EventLoopGroup boss = new NioEventLoopGroup();EventLoopGroup worker = new NioEventLoopGroup();//3.定義工作組serverBootstrap.group(boss,worker);//4.設置通道channelserverBootstrap.channel(NioServerSocketChannel.class);//A//serverBootstrap.channelFactory(new ReflectiveChannelFactory(NioServerSocketChannel.class));//舊版本的寫法,但是此過程在A中有同樣過程//5.添加handler,管道中的處理器,通過ChannelInitializer來構造serverBootstrap.childHandler(new ChannelInitializer<Channel>() {@Overrideprotected void initChannel(Channel channel) throws Exception {//此方法每次客戶端連接都會調用,是為通道初始化的方法//獲得通道channel中的管道鏈(執行鏈、handler鏈)ChannelPipeline pipeline = channel.pipeline();pipeline.addLast(new StringDecoder());pipeline.addLast("serverHandler1",new ServerHandler());pipeline.addLast("serverHandler2",new ServerHandler2());pipeline.addLast(new StringEncoder());System.out.println("success to initHandler!");}});//6.設置參數//設置參數,TCP參數serverBootstrap.option(ChannelOption.SO_BACKLOG, 2048); //連接緩沖池的大小serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);//維持鏈接的活躍,清除死鏈接serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true);//關閉延遲發送//7.綁定ip和porttry {ChannelFuture channelFuture = serverBootstrap.bind("0.0.0.0", 9099).sync();//Future模式的channel對象//7.5.監聽關閉channelFuture.channel().closeFuture().sync(); //等待服務關閉,關閉后應該釋放資源} catch (InterruptedException e) {System.out.println("server start got exception!");e.printStackTrace();}finally {//8.優雅的關閉資源boss.shutdownGracefully();worker.shutdownGracefully();}} }Handler1
package com.mym.netty.server;import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter;public class ServerHandler extends ChannelInboundHandlerAdapter {/** ChannelInboundHandlerAdapter:ChannelInboundHandlerAdapter是ChannelInboundHandler的一個簡單實現,默認情況下不會做任何處理,* 只是簡單的將操作通過fire*方法傳遞到ChannelPipeline中的下一個ChannelHandler中讓鏈中的下一個ChannelHandler去處理。** SimpleChannelInboundHandler:SimpleChannelInboundHandler支持泛型的消息處理,默認情況下消息處理完將會被自動釋放,無法提供* fire*方法傳遞給ChannelPipeline中的下一個ChannelHandler,如果想要傳遞給下一個ChannelHandler需要調用ReferenceCountUtil#retain方法。* */@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("ServerHandler receive msg:"+msg.toString());//寫消息:先得到channel,在寫如通道然后flush刷新通道把消息發出去。ctx.channel().writeAndFlush("this is ServerHandler reply msg happend at !"+System.currentTimeMillis());//把消息往下一個Handler傳ctx.fireChannelRead(msg);} }Handler2
package com.mym.netty.server;import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter;public class ServerHandler2 extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("ServerHandler2 receive msg:"+msg.toString());ctx.channel().writeAndFlush("this is ServerHandler2 reply msg happend at !"+System.currentTimeMillis());} }Netty4實現客戶端
客戶端服務類
package com.mym.netty.client;import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder;import java.io.BufferedReader; import java.io.InputStreamReader;/*** netty客戶端*/ public class NettySingleClient {public static void main(String[] args) {startClient();}public static void startClient(){//1.定義服務類Bootstrap clientBootstap = new Bootstrap();//2.定義執行線程組EventLoopGroup worker = new NioEventLoopGroup();//3.設置線程池clientBootstap.group(worker);//4.設置通道clientBootstap.channel(NioSocketChannel.class);//5.添加HandlerclientBootstap.handler(new ChannelInitializer<Channel>() {@Overrideprotected void initChannel(Channel channel) throws Exception {System.out.println("client channel init!");ChannelPipeline pipeline = channel.pipeline();pipeline.addLast("StringDecoder",new StringDecoder());pipeline.addLast("StringEncoder",new StringEncoder());pipeline.addLast("ClientHandler",new ClientHandler());}});//6.建立連接ChannelFuture channelFuture = clientBootstap.connect("0.0.0.0",9099);try {//7.測試輸入BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));while(true){System.out.println("請輸入:");String msg = bufferedReader.readLine();channelFuture.channel().writeAndFlush(msg);}} catch (Exception e) {e.printStackTrace();}finally {//8.關閉連接worker.shutdownGracefully();}} }客戶端的handler
package com.mym.netty.client;import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter;public class ClientHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("client receive msg:"+msg.toString());} }測試
啟動服務端和客戶端后,客戶端發送nihao!服務端回應,然后客戶端發送hello,服務端回應。?
服務端輸出
客戶端輸出
client channel init! 請輸入: nihao! 請輸入: client receive msg:this is ServerHandler reply msg happend at !1531893027697this is ServerHandler2 reply msg happend at !1531893027698 hello 請輸入: client receive msg:this is ServerHandler reply msg happend at !1531893045446this is ServerHandler2 reply msg happend at !1531893045447小結
需要注意的是,服務端和客戶端除了啟動類和socket channel不一樣以外,其他幾乎一致的操作。
總結
以上是生活随笔為你收集整理的Netty4服务端和客户端实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 惊呆!学习MySQL真的这一篇就够了!太
- 下一篇: netty4搭建简单的http服务器