1. 程式人生 > >網路程式設計之基於nio的Netty框架Demo

網路程式設計之基於nio的Netty框架Demo

36套java進階高階架構師視訊+38套大資料視訊  保證全是硬貨需要的

+微信:

du13797566440


首選引入netty jar包

/**

 * @author dlj2018年1月2日
 * netty服務端,實現非同步非阻塞處理訊息
 */
public class Server {


public static void main(String[] args) throws Exception {
//1 第一個執行緒組 是用於接收Client端連線的
EventLoopGroup bossGroup = new NioEventLoopGroup();
//2 第二個執行緒組 是用於實際的業務處理操作的
EventLoopGroup workerGroup = new NioEventLoopGroup();

//3 建立一個輔助類Bootstrap,就是對我們的Server進行一系列的配置
ServerBootstrap b = new ServerBootstrap(); 
//把倆個工作執行緒組加入進來
b.group(bossGroup, workerGroup)
//我要指定使用NioServerSocketChannel這種型別的通道(服務端通道型別)
.channel(NioServerSocketChannel.class)
//一定要使用 childHandler 去繫結具體的 事件處理器
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast(new ServerHandler());
}
});


//繫結指定的埠 進行監聽
ChannelFuture f = b.bind(8765).sync(); 

//Thread.sleep(1000000);
f.channel().closeFuture().sync();//主執行緒阻塞

bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
 


}

}

----------------------------------------------------------------------------------------------------------

//非阻塞服務端業務處理器
public class ServerHandler  extends ChannelHandlerAdapter {

/* 
* 當客戶端簡歷連線後做writeAndFlush後 自動讀取客戶端資料
* msg客戶端發來的訊息
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

//do something msg
ByteBuf buf = (ByteBuf)msg; //ByteBuf:netty封裝的緩衝區
byte[] data = new byte[buf.readableBytes()];  //readableBytes:緩衝區大小
buf.readBytes(data); //將緩衝區資料轉到data中
String request = new String(data, "utf-8");
System.out.println("Server: " + request);
//寫給客戶端
String response = "我是反饋的資訊";
//返回資料方式1
ctx.writeAndFlush(Unpooled.copiedBuffer( response.getBytes()));//Unpooled.copiedBuffer將bytep[]轉成buf
//返回資料方式2
// ctx.write(Unpooled.copiedBuffer( response.getBytes()));
// ctx.write(Unpooled.copiedBuffer( "hahhaha".getBytes()));
// ctx.flush();

//writeAndFlush.addListener(ChannelFutureListener.CLOSE);//ChannelFuture新增一個監聽器,向客戶端寫完資料後關閉連線(故netty可以實現短連線與長連線)



}

//發生異常後自動呼叫
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}


}

------------------------------------------------------------------------------------------------

/**
 * @author dlj2018年1月2日
 * netty 客戶的實現非同步非阻塞接受返回訊息
 */
public class Client {


public static void main(String[] args) throws Exception {

EventLoopGroup workgroup = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(workgroup)
.channel(NioSocketChannel.class)//NioSocketChannel客戶端通道型別
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast(new ClientHandler());
}
});

ChannelFuture cf1 = b.connect("127.0.0.1", 8765).sync();

//傳送資料方式1 用netty的bytebuf來存放資料
cf1.channel().writeAndFlush(Unpooled.copiedBuffer("777".getBytes()));
//傳送資料方式2
// ctx.write(Unpooled.copiedBuffer( response.getBytes()));
// ctx.write(Unpooled.copiedBuffer( "hahhaha".getBytes()));
// ctx.flush();

cf1.channel().closeFuture().sync();
workgroup.shutdownGracefully();

}
}

----------------------------------------------------------------

//非阻塞客戶端業務處理器
public class ClientHandler extends ChannelHandlerAdapter {


/* 讀取服務端資料
* msg服務端端發來的訊息
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
//do something msg
ByteBuf buf = (ByteBuf)msg; //ByteBuf:netty封裝的緩衝區
byte[] data = new byte[buf.readableBytes()];  //readableBytes:緩衝區大小
buf.readBytes(data); //將緩衝區資料轉到data中
String request = new String(data, "utf-8");
System.out.println("Client: " + request);


} finally {
ReferenceCountUtil.release(msg); //客戶端要顯示釋放訊息,服務端由於做了write操作裡面netty內部幫我們釋放了訊息
}
}


//發生異常時回撥方法
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}