netty使用

支持協議

  1. TCP/UDP
  2. HTTP/HTTPS
  3. WebSocket
  4. SPDY/HTTP2
  5. MQTT/CoAP

服務端

常用類

ServerBootstrap

服務端配置類

//設置線程組、parentGroup處理連接、childGroup處理I/O
group(EventLoopGroup parentGroup, EventLoopGroup childGroup)
//Channel通過何種方式獲取新的連接(NioServerSocketChannel、NioSocketChannel)
channel(Class<? extends C> channelClass)
//ServerChannel一些配置項、ChannelOption.SO_BACKLOG
option(ChannelOption option, T value)
//ServerChannel的子Channel的選項
childOption(ChannelOption childOption, T value)
//自定義ChannelInboundHandlerAdapter、編碼解碼器等
childHandler(ChannelHandler childHandler)

NioServerSocketChannel

服務端通道

Bootstrap

客戶端配置類

NioSocketChannel

客戶端通道

EventLoopGroup

事件循環組,就是個定時器任務,線程組。

NioEventLoopGroup

ChannelFuture

尚未發生的 I/O 操作

ChannelInboundHandlerAdapter

在接收到新的請求進行回調、這個類定義了一系列回調方法。常見的回調如下:

channelRead(ChannelHandlerContext ctx, Object msg) // 收到消息調用
exceptionCaught(ChannelHandlerContext ctx, Throwable cause) // 異常調用
channelInactive(ChannelHandlerContext ctx) throws Exception //連接斷開
channelActive(ChannelHandlerContext ctx) throws Exception //連接建立

ChannelOutboundHandlerAdapter

在請求進行響應、這個類定義了一系列適配方法。常見的適配如下:

代碼示例

1、新建通道處理類處理每一次I/O

import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;/*** Handles a server-side channel.*/
public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1)@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)// Discard the received data silently.((ByteBuf) msg).release(); // (3)}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)// Close the connection when an exception is raised.cause.printStackTrace();ctx.close();}
}

2、創建一個netty服務端

import io.netty.bootstrap.ServerBootstrap;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.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;/*** Discards any incoming data.*/
public class DiscardServer {private int port;public DiscardServer(int port) {this.port = port;}public void run() throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap(); // (2)b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) // (3).childHandler(new ChannelInitializer<SocketChannel>() { // (4)@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new DiscardServerHandler());}}).option(ChannelOption.SO_BACKLOG, 128)          // (5).childOption(ChannelOption.SO_KEEPALIVE, true); // (6)// Bind and start to accept incoming connections.// 服務端綁定端口ChannelFuture f = b.bind(port).sync(); // (7)// Wait until the server socket is closed.// In this example, this does not happen, but you can do that to gracefully// shut down your server.// 一直阻塞知道通道關閉、再優雅的關閉線程組shutdownGracefully()f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception {int port = 8080;if (args.length > 0) {port = Integer.parseInt(args[0]);}new DiscardServer(port).run();}
}

客戶端

代碼示例

public static void main(String[] args) throws Exception {String host = "192.168.32.29";int port = 8009;EventLoopGroup workerGroup = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap(); // (1)b.group(workerGroup); // (2)b.channel(NioSocketChannel.class); // (3)b.option(ChannelOption.SO_KEEPALIVE, true); // (4)b.handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new TimeClientHandler());}});// Start the client.ChannelFuture f = b.connect(host, port).sync(); // (5)// Wait until the connection is closed.f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();}}

數據解析

1、為了正確的解析傳遞的數據、粘包、半包等問題。需要明確包的固定長度或者固定的解析方法、如長度、特殊字符結尾等等。
2、編寫編碼、解碼類 注意:新的編碼、解碼器需要在通道內配置 ChannelInitializer

public class TimeDecoder extends ByteToMessageDecoder { // (1)@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) { // (2)if (in.readableBytes() < 4) {return; // (3)}//自定義UnixTime的POJO、從通道讀取四個字節、做一次轉換out.add(new UnixTime(in.readUnsignedInt())); //(4)}
}

解碼器

public class TimeEncoder extends MessageToByteEncoder<UnixTime> {@Overrideprotected void encode(ChannelHandlerContext ctx, UnixTime msg, ByteBuf out) {out.writeInt((int)msg.value());}
}

也可以通過ChannelOutboundHandler 實現將回傳POJO轉換為 ByteBuf。這比編寫解碼器要簡單得多,因為在對消息進行編碼時無需處理數據包碎片和匯編。UnixTime

public class TimeEncoder extends ChannelOutboundHandlerAdapter {@Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {UnixTime m = (UnixTime) msg;ByteBuf encoded = ctx.alloc().buffer(4);encoded.writeInt((int)m.value());ctx.write(encoded, promise); // (1)}
}

TimeDecoder 應用到通道中指定TimeClientHandler

b.handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new TimeDecoder(), new TimeClientHandler());}
});

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/206754.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/206754.shtml
英文地址,請注明出處:http://en.pswp.cn/news/206754.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【擴散模型】ControlNet從原理到實戰

ControlNet從原理到實戰 ControlNet原理ControlNet應用于大型預訓練擴散模型ControlNet訓練過程ControlNet示例1 ControlNet與Canny Edge2. ControlNet與Depth3. ControlNet與M-LSD Lines4. ControlNet與HED Boundary ControlNet實戰Canny Edge實戰Open Pose 小結參考資料 Cont…

Linux系統上RabbitMQ安裝教程

一、安裝前環境準備 Linux&#xff1a;CentOS 7.9 RabbitMQ Erlang 1、系統內須有C等基本工具 yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c kernel-devel m4 ncurses-devel tk tc xz socat2、下載安裝包 1&#xff09;首先&a…

[linux] kaggle 數據集用linux下載

你可以通過以下步驟獲取Kaggle的下載鏈接并在Linux中進行下載&#xff1a; 首先&#xff0c;確保你已經安裝了Python和Kaggle API。如果沒有安裝&#xff0c;你可以通過以下命令安裝&#xff1a; pip install kaggle 接著&#xff0c;你需要在Kaggle網站上獲取API Token。登錄…

時間相關類

內容 JDK7時間相關類JDK8時間相關類 第一章 Date類 1.1 Date概述 java.util.Date類 表示特定的瞬間&#xff0c;精確到毫秒。 繼續查閱Date類的描述&#xff0c;發現Date擁有多個構造函數&#xff0c;只是部分已經過時&#xff0c;我們重點看以下兩個構造函數 public Dat…

【PyTorch】 暫退法(dropout)

文章目錄 1. 理論介紹2. 實例解析2.1. 實例描述2.2. 代碼實現2.2.1. 主要代碼2.2.2. 完整代碼2.2.3. 輸出結果 1. 理論介紹 線性模型泛化的可靠性是有代價的&#xff0c;因為線性模型沒有考慮到特征之間的交互作用&#xff0c;由此模型靈活性受限。泛化性和靈活性之間的基本權…

Docker構建自定義鏡像

創建一個docker-demo的文件夾,放入需要構建的文件 主要是配置Dockerfile文件 第一種配置方法 # 指定基礎鏡像 FROM ubuntu:16.04 # 配置環境變量&#xff0c;JDK的安裝目錄 ENV JAVA_DIR/usr/local# 拷貝jdk和java項目的包 COPY ./jdk8.tar.gz $JAVA_DIR/ COPY ./docker-demo…

Java基礎50題: 21.實現一個方法printArray, 以數組為參數,循環訪問數組中的每個元素,打印每個元素的值.

概述 實現一個方法printArray, 以數組為參數,循環訪問數組中的每個元素,打印每個元素的值. 代碼 public static void printArray(int[] array) {for (int i 0; i < array.length; i) {System.out.println(array[i] " ");}System.out.println();}public static…

【數據結構c實現】順序表實現

文章目錄 線性表線性表的順序實現結點結構結點初始化增配空間Inc打印順序表show_list線性表長度length尾部插入push_back頭部插入push_front尾部刪除pop_back頭部刪除pop_front按位置插入insert_pos按值查找find按位置刪除delete_pos按值刪除delete_val排序sort(冒泡&#xff1…

云上業務DDoS與CC攻擊防護實踐

案例背景&#xff1a;DDoS攻擊來勢洶洶&#xff0c;云上業務面臨威脅 某網絡科技有限公司&#xff0c;SaaS化創業公司&#xff0c;業務基于云上開展。其業務主要為各大網站提供安全驗證服務&#xff0c;且市場占有率較高&#xff0c;服務客戶遍布金融、直播、教育、電商等多個領…

【日常總結】mybatis-plus WHERE BINARY 中文查不出來

目錄 一、場景 二、問題 三、原因 四、解決方案 五、拓展&#xff08;全表全字段修改字符集一鍵更改&#xff09; 準備工作&#xff1a;做好整個庫備份 1. 全表一鍵修改 Stage 1&#xff1a;運行如下查詢 Stage 2&#xff1a;復制sql語句 Stage 3&#xff1a;執行即可…

100. 相同的樹(Java)

目錄 解法&#xff1a; 官方解法&#xff1a; 方法一&#xff1a;深度優先搜索 復雜度分析 時間復雜度&#xff1a; 空間復雜度&#xff1a; 方法二&#xff1a;廣度優先搜索 復雜度分析 時間復雜度&#xff1a; 空間復雜度&#xff1a; 給你兩棵二叉樹的根節點 p 和…

L1-028:判斷素數

題目描述 本題的目標很簡單&#xff0c;就是判斷一個給定的正整數是否素數。 輸入格式&#xff1a; 輸入在第一行給出一個正整數N&#xff08;≤ 10&#xff09;&#xff0c;隨后N行&#xff0c;每行給出一個小于231的需要判斷的正整數。 輸出格式&#xff1a; 對每個需要判斷的…

Kotlin(十五) 高階函數詳解

高階函數的定義 高階函數和Lambda的關系是密不可分的。在之前的文章中&#xff0c;我們熟悉了Lambda編程的基礎知識&#xff0c;并且掌握了一些與集合相關的函數式API的用法&#xff0c;如map、filter函數等。另外&#xff0c;我們也了解了Kotlin的標準函數&#xff0c;如run、…

vuepress-----22、其他評論方案

vuepress 支持評論 本文講述 vuepress 站點如何集成評論系統&#xff0c;選型是 valineleancloud, 支持匿名評論&#xff0c;缺點是數據沒有存儲在自己手里。市面上也有其他的方案, 如 gitalk,vssue 等, 但需要用戶登錄 github 才能發表評論, 但 github 經常無法連接,導致體驗…

[wp]“古劍山”第一屆全國大學生網絡攻防大賽 Web部分wp

“古劍山”第一屆全國大學生網絡攻防大賽 群友說是原題杯 哈哈哈哈 我也不懂 我比賽打的少 Web Web | unse 源碼&#xff1a; <?phpinclude("./test.php");if(isset($_GET[fun])){if(justafun($_GET[fun])){include($_GET[fun]);}}else{unserialize($_GET[…

使用cmake構建的工程的編譯方法

1、克隆項目工程 2、進入到工程目錄 3、執行 mkdir build && cd build 4、執行 cmake .. 5、執行 make 執行以上步驟即可完成對cmake編寫的工程進行編譯 &#xff0c;后面只需執行你的編譯結果即可 $ git clone 你想要克隆的代碼路徑 $ cd 代碼文件夾 $ mkdir bu…

測試:SRE

SRE&#xff08;Site Reliability Engineering&#xff0c;站點可靠性工程&#xff09;是一種關注于構建、運行和維護大規模分布式系統的工程學科。它旨在確保系統在各種故障情況下仍然可用、可靠和高效。 SRE的核心目標是通過軟件工程的方法來解決系統可靠性問題&#xff0c;…

WPF DataGrid 里面的ToggleButton點擊不生效

已解決&#xff1a;根本原因是沒寫UpdateSourceTriggerPropertyChanged <ToggleButton IsChecked"{Binding PathIsEnabled,ModeTwoWay,UpdateSourceTriggerPropertyChanged}"/> 具體原因參考下面文章&#xff1a;鳴謝作者 WPF 數據集合綁定到DataGrid、ListV…

vmware安裝centos7總結

vmware安裝centos7總結 文章目錄 vmware安裝centos7總結一、配置網絡&#xff08;橋接模式&#xff09;二、配置yum源&#xff08;連網配置&#xff09;三、可視化界面四、安裝Docker五、安裝DockerUI 一、配置網絡&#xff08;橋接模式&#xff09; 網絡連接模式選擇橋接模式…

Ubuntu安裝nvidia GPU顯卡驅動教程

Ubuntu安裝nvidia顯卡驅動 1.安裝前安裝必要的依賴 sudo apt-get install build-essential sudo apt-get install g sudo apt-get install make2.到官網下載對應驅動 https://www.nvidia.cn/Download/index.aspx?langcn 3.卸載原有驅動 sudo apt-get remove --purge nvidi…