一、netty初學,簡單的echo服務器,客戶端

無論服務器還是客戶端都是由下面兩步組成
1、ChannelHandler 用與處理各種事件的邏輯處理。決定了連接創建後和接收到信息後該如何處理。
直接或簡接要實現ChannelInboundHandler 接口.
2、Bootstrap啓動服務器或客戶端 服務器用 ServerBootstrap 客戶端用 BootStrap。
pom
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.0.29.Final</version>
</dependency>


EchoServerChannelHandler
packagetest01;

importio.netty.buffer.ByteBuf;
importio.netty.buffer.Unpooled;
importio.netty.channel.ChannelFutureListener;
importio.netty.channel.ChannelHandlerContext;
importio.netty.channel.ChannelInboundHandlerAdapter;
importio.netty.util.CharsetUtil;

/**
* Created by wujiazhen on 2018/1/15.
*/
public classEchoServerChannelHandlerextendsChannelInboundHandlerAdapter {

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)throwsException {
ByteBuf in = (ByteBuf)msg;
System.out.println("server receive:"+in.toString(CharsetUtil.UTF_8));
ctx.write(msg);
}

@Override
public void channelReadComplete(ChannelHandlerContext ctx)throwsException {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)throwsException {
cause.printStackTrace();//5
ctx.close();
}
}

服務器啓動
packagetest01;

importio.netty.bootstrap.ServerBootstrap;
importio.netty.channel.*;
importio.netty.channel.nio.NioEventLoopGroup;
importio.netty.channel.socket.SocketChannel;
importio.netty.channel.socket.nio.NioServerSocketChannel;

importjava.net.InetSocketAddress;
importjava.util.concurrent.TimeUnit;

/**
* Created by wujiazhen on 2018/1/15.
*/
public classEchoServer {
private int port;
publicEchoServer(){};
publicEchoServer(intport){
this.port=port;
}
public static void main(String args[]){
newEchoServer(2000).start();

}
public void start() {
NioEventLoopGroup group =newNioEventLoopGroup();
try{
/*
1.創建 EventLoopGroup
2.創建 ServerBootstrap
3.指定使用 NIO 的傳輸 Channel
4.設置 socket 地址使用所選的端口
5.添加 EchoServerHandler 到 Channel 的 ChannelPipeline
*/
ServerBootstrap bootstrap = newServerBootstrap()
.channel(NioServerSocketChannel.class)
.group(group)
.localAddress(newInetSocketAddress(this.getPort()))
.childHandler(newChannelInitializer<SocketChannel>() {
public void initChannel(SocketChannel socketChannel)throwsException {
/*
ChannelInitializer 。當一個新的連接被接受,一個新的子 Channel 將被創建,
ChannelInitializer 會添加我們EchoServerHandler 的實例到 Channel 的 ChannelPipeline。
正如我們如前所述,如果有入站信息,這個處理器將被通知。
*/
socketChannel.pipeline().addLast(newEchoServerChannelHandler());
}
});
// 6.綁定的服務器;sync 等待服務器關閉
ChannelFuture future = bootstrap.bind().sync();
System.out.println(EchoServer.class.getName() + " started and listen on "+ future.channel().localAddress());
//7.關閉 channel 和 塊,直到它被關閉
future.channel().closeFuture().sync();
}catch(InterruptedException e) {
e.printStackTrace();
}finally{
try{
group.shutdownGracefully().sync();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public int getPort() {
returnport;
}

public void setPort(intport) {
this.port= port;
}
}

客戶端handler
packagetest01;

importio.netty.buffer.ByteBuf;
importio.netty.buffer.Unpooled;
importio.netty.channel.ChannelHandlerContext;
importio.netty.channel.SimpleChannelInboundHandler;
importio.netty.util.CharsetUtil;

/**
* Created by wujiazhen on 2018/1/15.
*/
public classEchoClientChannelHandlerextendsSimpleChannelInboundHandler {
protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg)throwsException {
ByteBuf in = (ByteBuf)msg;
System.out.println("client receive:"+in.toString(CharsetUtil.UTF_8));
}

@Override
public void channelActive(ChannelHandlerContext ctx)throwsException {
System.out.println("connect success");
ctx.writeAndFlush(Unpooled.copiedBuffer("客戶端:建立.....",CharsetUtil.UTF_8));
super.channelActive(ctx);
}
}

客戶端啓動
packagetest01;

importio.netty.bootstrap.Bootstrap;
importio.netty.channel.ChannelFuture;
importio.netty.channel.ChannelInitializer;
importio.netty.channel.nio.NioEventLoopGroup;
importio.netty.channel.socket.SocketChannel;
importio.netty.channel.socket.nio.NioServerSocketChannel;
importio.netty.channel.socket.nio.NioSocketChannel;

/**
* Created by wujiazhen on 2018/1/15.
*/
public classEchoClient {

public static void main(String[] args){
newEchoClient().start();
}

public void start(){
NioEventLoopGroup group =newNioEventLoopGroup();
try{
Bootstrap bootstrap =newBootstrap();
bootstrap.group(group)
//區別與服務端的channel,客戶端用NioSocketChannel
.channel(NioSocketChannel.class)
.remoteAddress("127.0.0.1",2000)
.handler(newChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel socketChannel)throwsException {
socketChannel.pipeline().addLast(newEchoClientChannelHandler());
}
});
ChannelFuture sync = bootstrap.connect().sync();
sync.channel().closeFuture().sync();
}catch(InterruptedException e) {
e.printStackTrace();
}finally{
try{
group.shutdownGracefully().sync();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章