日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

netty系列之:请netty再爱UDT一次

發(fā)布時間:2023/12/14 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 netty系列之:请netty再爱UDT一次 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 簡介
  • netty對UDT的支持
    • 搭建一個支持UDT的netty服務
    • 異常來襲
    • TypeUDT和KindUDT
    • 構建ChannelFactory
    • SelectorProviderUDT
  • 使用UDT
  • 總結

簡介

UDT是一個非常優(yōu)秀的協(xié)議,可以提供在UDP協(xié)議基礎上進行高速數據傳輸。但是可惜的是在netty 4.1.7中,UDT傳輸協(xié)議已經被標記為Deprecated了!

意味著在后面的netty版本中,你可能再也看不到UDT協(xié)議了.

優(yōu)秀的協(xié)議怎么能夠被埋沒,讓我們揭開UDT的面紗,展示其優(yōu)秀的特性,讓netty再愛UDT一次吧。

netty對UDT的支持

netty對UDT的支持體現在有一個專門的UDT包來處理UDT相關事情:package io.netty.channel.udt。

這個包里面主要定義了UDT的各種channel、channel配置、UDT消息和提供ChannelFactory和SelectorProvider的工具類NioUdtProvider.

搭建一個支持UDT的netty服務

按照netty的標準流程,現在是需要創(chuàng)建一個netty服務的時候了。

netty創(chuàng)建server服務無非就是創(chuàng)建EventLoop、創(chuàng)建ServerBootstrap、綁定EventLoop、指定channel類型就完了,非常的簡單。

唯一不同的就是具體的childHandler,可能根據具體協(xié)議的不同使用不同的處理方式。

當然,如果不是NioSocketChannel,那么對應的ChannelFactory和SelectorProvider也會有所變化。

沒關系,我們先看下如何創(chuàng)建支持UDT的netty服務:

final ThreadFactory acceptFactory = new DefaultThreadFactory("accept");final ThreadFactory connectFactory = new DefaultThreadFactory("connect");final NioEventLoopGroup acceptGroup = new NioEventLoopGroup(1, acceptFactory, NioUdtProvider.BYTE_PROVIDER);final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1, connectFactory, NioUdtProvider.BYTE_PROVIDER);final ServerBootstrap boot = new ServerBootstrap();boot.group(acceptGroup, connectGroup).channelFactory(NioUdtProvider.BYTE_ACCEPTOR).option(ChannelOption.SO_BACKLOG, 10).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<UdtChannel>() {@Overridepublic void initChannel(final UdtChannel ch) {ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO),new UDTEchoServerHandler());}});// 開啟服務final ChannelFuture future = boot.bind(PORT).sync();

可以看到,UDT和普通netty socket服務不同的地方在于它的selector和channelFactory都是由NioUdtProvider來提供了。

NioUdtProvider是netty核心包中的內容,他提供了對UDT的有用封裝,我們不需要要懂太多UDT內部的實現,就可以使用UDT協(xié)議,是不是很美妙。

異常來襲

如果有小伙伴興沖沖的拿上面這段代碼去嘗試運行,那么很可惜你會得到異常,異常大概類似下面的情況:

包com.barchart.udt找不到!

什么?直接使用netty包中的類居然會報錯?是可忍孰不可忍!

我們來仔細分析一下,這里只有一個新的類就是NioUdtProvider,打開NioUdtProvider的源碼,在import一欄,我們赫然發(fā)現居然引用了不屬于netty的包,就是這些包報錯了:

import com.barchart.udt.SocketUDT; import com.barchart.udt.TypeUDT; import com.barchart.udt.nio.ChannelUDT; import com.barchart.udt.nio.KindUDT; import com.barchart.udt.nio.RendezvousChannelUDT; import com.barchart.udt.nio.SelectorProviderUDT;

雖然很詭異,但是我們要想程序跑起來還是需要找出這些依賴包,經過本人的跋山涉水、翻山越嶺終于功夫不負苦心人,下面的依賴包找到了:

<dependency><groupId>com.barchart.udt</groupId><artifactId>barchart-udt-core</artifactId><version>2.3.0</version></dependency><dependency><groupId>com.barchart.udt</groupId><artifactId>barchart-udt-bundle</artifactId><version>2.3.0</version></dependency>

netty核心包居然要依賴與第三方庫,這可能就是netty準備刪除對UDT支持的原因吧。

TypeUDT和KindUDT

如果你去查看barchart中類的具體信息,就會發(fā)現這個包的作者有個癖好,喜歡把類后面帶上一個UDT。

當你看到滿屏的類都是以UDT結尾的時候,沒錯,它就是netty UDT依賴的包barchart本包了。

大牛們開發(fā)的包我們不能說他不好,只能說看起來有點累…

barchart包中有兩個比較核心的用來區(qū)分UDT type和kind的兩個類,分別叫做TypeUDT和KindUDT.

Type和kind翻譯成中文好像沒太大區(qū)別。但是兩者在UDT中還是有很大不同的。

TypeUDT表示的是UDT socket的模式。它有兩個值,分別是stream和datagram:

STREAM(1),DATAGRAM(2),

表示數據傳輸是以字節(jié)流的形式還是以數據報文消息的格式來進行傳輸。

KindUDT則用來區(qū)分是服務器端還是客戶端,它有三種模式:

ACCEPTOR, CONNECTOR, RENDEZVOUS

server模式對應的是ACCEPTOR,用來監(jiān)聽和接收連接.它的代表是ServerSocketChannelUDT,通過調用accept()方法返回一個CONNECTOR.

CONNECTOR模式可以同時在客戶端和服務器端使用,它的代表類是SocketChannelUDT.

如果是在server端,則是通過調用server端的accept方法生成的。如果是在客戶端,則表示的是客戶端和服務器端之間的連接。

還有一種模式是RENDEZVOUS模式。這種模式表示的是連接的每一側都有對稱對等的channel。也就是一個雙向的模式,它的代表類是RendezvousChannelUDT。

構建ChannelFactory

上面提到的兩種Type和三種Kind都是用來定義channel的,所以如果將其混合,會生成六種不同的channelFactory,分別是:

public static final ChannelFactory<UdtServerChannel> BYTE_ACCEPTOR = new NioUdtProvider<UdtServerChannel>(TypeUDT.STREAM, KindUDT.ACCEPTOR);public static final ChannelFactory<UdtChannel> BYTE_CONNECTOR = new NioUdtProvider<UdtChannel>(TypeUDT.STREAM, KindUDT.CONNECTOR);public static final ChannelFactory<UdtChannel> BYTE_RENDEZVOUS = new NioUdtProvider<UdtChannel>(TypeUDT.STREAM, KindUDT.RENDEZVOUS);public static final ChannelFactory<UdtServerChannel> MESSAGE_ACCEPTOR = new NioUdtProvider<UdtServerChannel>(TypeUDT.DATAGRAM, KindUDT.ACCEPTOR);public static final ChannelFactory<UdtChannel> MESSAGE_CONNECTOR = new NioUdtProvider<UdtChannel>(TypeUDT.DATAGRAM, KindUDT.CONNECTOR);public static final ChannelFactory<UdtChannel> MESSAGE_RENDEZVOUS = new NioUdtProvider<UdtChannel>(TypeUDT.DATAGRAM, KindUDT.RENDEZVOUS);

這些channelFactory通過調用newChannel()方法來生成新的channel。

但是歸根節(jié)點,這些channel最后是調用SelectorProviderUDT的from方法來生成channel的。

SelectorProviderUDT

SelectorProviderUDT根據TypeUDT的不同有兩種,分別是:

public static final SelectorProviderUDT DATAGRAM = new SelectorProviderUDT(TypeUDT.DATAGRAM);public static final SelectorProviderUDT STREAM = new SelectorProviderUDT(TypeUDT.STREAM);

可以通過調用他的三個方法來生成對應的channel:

public RendezvousChannelUDT openRendezvousChannel() throws IOException {final SocketUDT socketUDT = new SocketUDT(type);return new RendezvousChannelUDT(this, socketUDT);}public ServerSocketChannelUDT openServerSocketChannel() throws IOException {final SocketUDT serverSocketUDT = new SocketUDT(type);return new ServerSocketChannelUDT(this, serverSocketUDT);}public SocketChannelUDT openSocketChannel() throws IOException {final SocketUDT socketUDT = new SocketUDT(type);return new SocketChannelUDT(this, socketUDT);}

使用UDT

搭建好了netty服務器,剩下就是編寫Handler對數據進行處理了。

這里我們簡單的將客戶端寫入的數據再回寫。客戶端先創(chuàng)建一個message:

message = Unpooled.buffer(UDTEchoClient.SIZE);message.writeBytes("www.flydean.com".getBytes(StandardCharsets.UTF_8));

再寫入到server端:

public void channelActive(final ChannelHandlerContext ctx) {log.info("channel active " + NioUdtProvider.socketUDT(ctx.channel()).toStringOptions());ctx.writeAndFlush(message);}

服務器端通過channelRead方法來接收:

public void channelRead(final ChannelHandlerContext ctx, Object msg) {ctx.write(msg);}

總結

以上就是netty中使用UDT的原理和一個簡單的例子。

本文的例子可以參考:learn-netty4

本文已收錄于 http://www.flydean.com/40-netty-udt-support/

最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發(fā)現!

歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!

總結

以上是生活随笔為你收集整理的netty系列之:请netty再爱UDT一次的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。