Netty----什麼是Netty學習
什麼Netty?
Netty是由JBOSS提供的一個java開源框架。Netty提供非同步的、事件驅動的網路應用程式框架和工具,用以快速開發高效能、高可靠性的網路伺服器和客戶端程式。
也就是說,Netty 是一個基於NIO的客戶、伺服器端程式設計框架,使用Netty 可以確保你快速和簡單的開發出一個網路應用,例如實現了某種協議的客戶,服務端應用。Netty相當簡化和流線化了網路應用的程式設計開發過程,例如,TCP和UDP的socket服務開發。
我們下面編寫四個類
1.用於接收資料的伺服器端Socket
2.用於接收客戶端的訊息,用於接收和反饋客戶端發出的訊息類ServertHandler
3.用於傳送資料的伺服器端Client
4.用於傳送資料和接收伺服器端發出的資料處理類ClientHandler
public class Server {
public static void main(String[] args) throws InterruptedException {
//1.第一個執行緒組是用於接收Client端連線的
EventLoopGroup bossGroup = new NioEventLoopGroup();
//2.第二個執行緒組是用於實際的業務處理的
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup);//繫結兩個執行緒池
b.channel(NioServerSocketChannel.class);//指定NIO的模式,如果是客戶端就是NioSocketChannel
b.option(ChannelOption.SO_BACKLOG, 1024);//TCP的緩衝區設定
b.option(ChannelOption.SO_SNDBUF, 32*1024);//設定傳送緩衝的大小
b.option(ChannelOption.SO_RCVBUF, 32*1024);//設定接收緩衝區大小
b.option(ChannelOption.SO_KEEPALIVE, true);//保持連續
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());//拆包粘包定義結束字串(第一種解決方案)
sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,buf));//在管道中加入結束字串
// sc.pipeline().addLast(new FixedLengthFrameDecoder(200));第二種定長
sc.pipeline().addLast(new StringDecoder());//定義接收型別為字串把ByteBuf轉成String
sc.pipeline().addLast(new ServerHandler());//在這裡配置具體資料接收方法的處理
}
});
ChannelFuture future = b.bind(8765).sync();//繫結埠
future.channel().closeFuture().sync();//等待關閉(程式阻塞在這裡等待客戶端請求)
bossGroup.shutdownGracefully();//關閉執行緒
workerGroup.shutdownGracefully();//關閉執行緒
}
}
1.在上面這個Server.java中,我們都要定義兩個執行緒池,boss和worker,boss是用於管理連線到server端的client的連線數的執行緒池,而woeker是用於管理實際操作的執行緒池。
2.ServerBootstrap用一個ServerSocketChannelFactory 來例項化。ServerSocketChannelFactory 有兩種選擇,一種是NioServerSocketChannelFactory,一種是OioServerSocketChannelFactory。 前者使用NIO,後則使用普通的阻塞式IO。它們都需要兩個執行緒池例項作為引數來初始化,一個是boss執行緒池,一個是worker執行緒池。
3.然後使ServerBookstrap管理boss和worker執行緒池。並且設定各個緩衝區的大小。
4.這裡的事件處理類經常會被用來處理一個最近的已經接收的Channel。ChannelInitializer是一個特殊的處理類,他的目的是幫助使用者配置一個新的Channel。也許你想通過增加一些處理類比如NettyServerHandler來配置一個新的Channel 或者其對應的ChannelPipeline來實現你的網路程式。 當你的程式變的複雜時,可能你會增加更多的處理類到pipline上,然後提取這些匿名類到最頂層的類上。
5.在使用原始的encoder、decoder的情況下,Netty傳送接收資料都是按照ByteBuf的形式,其它形式都是不合法的。 而在上面這個Socket中,我使用sc.pipeline().addLast()這個方法設定了接收為字串型別,注意:只能設定接收為字串型別,傳送還是需要傳送ByteBuf型別的資料。而且在這裡我還設定了以$_為結尾的字串就代表了本次請求字串的結束。
6.通過b.bind繫結埠,用於監聽的埠號。
public class ServerHandler extends ChannelHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String body = (String) msg;
System.out.println("server"+body);//前面已經定義了接收為字串,這裡直接接收字串就可以
//服務端給客戶端的響應
String response= " hi client!$_";//傳送的資料以定義結束的字串結尾
ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()));//傳送必須還是ByteBuf型別
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
ServertHandler繼承自 ChannelHandlerAdapter,這個類實現了ChannelHandler介面,ChannelHandler提供了許多事件處理的介面方法,然後你可以覆蓋這些方法。現在僅僅只需要繼承ChannelHandlerAdapter類而不是你自己去實現介面方法。
1.由於我們再server端開始的時候已經定義了接收型別為String,所以在這裡我們接收到的msg直接強轉成String就可以了。同時也要定義以什麼為一次請求的結尾。
public class Client {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup worker = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(worker)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,buf));
sc.pipeline().addLast(new StringDecoder());
sc.pipeline().addLast(new ClientHandler());
}
});
ChannelFuture f=b.connect("127.0.0.1",8765).sync();
f.channel().writeAndFlush(Unpooled.copiedBuffer(" hi server2$_".getBytes()));
f.channel().writeAndFlush(Unpooled.copiedBuffer(" hi server3$_".getBytes()));
f.channel().writeAndFlush(Unpooled.copiedBuffer(" hi server4$_".getBytes()));
f.channel().closeFuture().sync();
worker.shutdownGracefully();
}
}
client端和Socket端幾乎程式碼相同,只是client端用的不是ServerBootstrap而是Bootstrap來管理連線。這裡沒什麼好說的。
public class ClientHandler extends ChannelHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
System.out.println("client"+msg.toString());
} finally {
ReferenceCountUtil.release(msg);//釋放緩衝區
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
ClientHandler和ServertHandler程式碼和原理也是一樣,只是在client端我們要釋放緩衝區。為什麼在ServerHandler我們不需要釋放呢 ?因為在ServertHandler我們呼叫ctx.writeAndFlush方法的時候,這個方法預設已經幫我們釋放了緩衝區。
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha1</version>
</dependency>
<!-- 如果我們想要在Netty中傳遞一個物件該怎麼辦呢 ?那麼這個時候我們可以結合Marshalling來傳遞。首先需要匯入兩個Marshalling的依賴包 -->
<dependency>
<groupId>org.jboss.marshalling</groupId>
<artifactId>jboss-marshalling</artifactId>
<version>2.0.0.CR1</version>
</dependency>
<dependency>
<groupId>org.jboss.marshalling</groupId>
<artifactId>jboss-marshalling-serial</artifactId>
<version>2.0.0.CR1</version>
</dependency>
</dependencies>
相關文章
- 為什麼要學習Netty?Netty
- 什麼是 NettyNetty
- Netty是什麼,Netty為什麼速度這麼快,執行緒模型分析Netty執行緒模型
- 【學習】NPM是什麼NPM
- 深度學習是什麼深度學習
- 【學習】介面是什麼?實現原理的是什麼?
- 打算寫一些Netty的文章了,先聊聊為什麼要學習NettyNetty
- 什麼是遷移學習?什麼時候使用遷移學習?遷移學習
- kafka學習(二)-------- 什麼是KafkaKafka
- Docker 學習 一:Docker 是什麼Docker
- Docker 學習 一,Docker 是什麼Docker
- 什麼是機器學習治理?機器學習
- Python優勢是什麼?為什麼要學習?Python
- 什麼是linux?學習linux需要什麼語言?Linux
- 什麼是linux?Linux需要學習什麼語言?Linux
- 什麼是 AI、機器學習與深度學習?AI機器學習深度學習
- 什麼是AI、機器學習與深度學習?AI機器學習深度學習
- 自學JAVA學習路線是什麼?Java
- Linux是什麼系統?為什麼要學習Linux?Linux
- 什麼是Spring Boot?為什麼要學習Spring Boot?Spring Boot
- 什麼是shell指令碼?Linux為什麼學習shell?指令碼Linux
- 漫畫:什麼是機器學習機器學習
- 機器學習到底是什麼?機器學習
- web前端學習路線是什麼Web前端
- 漫畫版:什麼是深度學習?深度學習
- 什麼是機器學習MLOps? - kdnuggets機器學習
- 什麼是Netty編解碼,Netty編解碼器有哪些?Protostuff怎麼使用?Netty
- DNS域名解析的流程是什麼?學習linux主要學什麼DNSLinux
- Netty之旅二:口口相傳的高效能Netty到底是什麼?Netty
- netty學習(三)springboot+netty+mybatisNettySpring BootMyBatis
- 什麼是Web前端?Web前端要學習什麼內容?Web前端
- 什麼是java?為什麼大家都學習java技術?Java
- Java到底是什麼?學習java可以做什麼呢?Java
- Linux是什麼?為什麼推薦學習Linux技術?Linux
- 【NLP學習其三】在學習什麼是嵌入之前,你應該瞭解什麼是詞語表徵
- 到底什麼是Linux?快進來學習!Linux
- 漫畫版:什麼是機器學習?機器學習
- 什麼是深度學習的影片標註?深度學習
- Node.js 是什麼以及如何學習?Node.js