Netty學習(3): 客戶端和服務端的例子
阿新 • • 發佈:2018-11-01
服務端:
package com.server; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; 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; /** * 服務端 * * @author xiajie * */ public class Server { public static void main(String[] args) { /** * 服務啟動類 */ ServerBootstrap bootstrap = new ServerBootstrap(); /** * boss和worker * 這兩個可以理解為執行緒池,EventLoopGroup內部是對執行緒池的封裝 */ EventLoopGroup boss = new NioEventLoopGroup(); EventLoopGroup worker = new NioEventLoopGroup(); try { //設定執行緒池 bootstrap.group(boss, worker); //設定socket工廠、 bootstrap.channel(NioServerSocketChannel.class); //設定管道工廠 bootstrap.childHandler(new ChannelInitializer<Channel>() { /** * 管道最終要設定到處理器中 */ @Override protected void initChannel(Channel ch) throws Exception { /** * 設定解碼處理器 */ ch.pipeline().addLast(new StringDecoder()); /** * 設定編碼處理器 */ ch.pipeline().addLast(new StringEncoder()); ch.pipeline().addLast(new ServerHandler()); } }); //設定引數,TCP引數 bootstrap.option(ChannelOption.SO_BACKLOG, 2048);//serverSocketchannel的設定,連結緩衝池的大小 bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);//socketchannel的設定,維持連結的活躍,清除死連結 bootstrap.childOption(ChannelOption.TCP_NODELAY, true);//socketchannel的設定,關閉延遲傳送 //繫結埠 ChannelFuture future = bootstrap.bind(10201); System.out.println("start"); //等待服務端關閉 future.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); System.out.print(e); } finally{ //釋放資源 boss.shutdownGracefully(); worker.shutdownGracefully(); } } }
package com.server; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; /** * 服務端訊息處理 * @author xiajie * */ public class ServerHandler extends SimpleChannelInboundHandler<String> { /** * 訊息接收處理方法 */ @Override protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println("服務端收到"+ctx.channel().remoteAddress()+"發來的訊息:"+msg); ctx.channel().writeAndFlush("hi 服務已經收到你IP="+ctx.channel().remoteAddress()+"發的訊息"); ctx.writeAndFlush("hi 服務已經收到你發的訊息"); } /** * 當有新的客戶端連線到服務端 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("channelActive.......新的客戶端連線到服務端"); } /** * 當客戶端斷開與服務端的連線 */ @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("channelInactive.......客戶端斷開與服務端的連線"); } /** * 異常 */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); } }
客戶端
package com.client; import java.io.BufferedReader; import java.io.InputStreamReader; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; 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.nio.NioSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; /** * netty的客戶端 * @author xiajie * */ public class Client { public static void main(String[] args) { //服務類 Bootstrap bootstrap = new Bootstrap(); //worker EventLoopGroup worker = new NioEventLoopGroup(); try { //設定執行緒池 bootstrap.group(worker); //設定socket工廠、 bootstrap.channel(NioSocketChannel.class); //設定管道 bootstrap.handler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) throws Exception { ch.pipeline().addLast(new StringDecoder()); ch.pipeline().addLast(new StringEncoder()); ch.pipeline().addLast(new ClientHandler()); } }); ChannelFuture connect = bootstrap.connect("127.0.0.1", 10201); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); while(true){ System.out.println("請輸入:"); String msg = bufferedReader.readLine(); connect.channel().writeAndFlush(msg); } } catch (Exception e) { e.printStackTrace(); } finally{ worker.shutdownGracefully(); } } }
package com.client;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
* 客戶端訊息處理
* @author xiajie
*
*/
public class ClientHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("客戶端收到訊息:"+msg);
}
}
執行結果