欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot中用 Netty 開(kāi)啟UDP服務(wù)方式

 更新時(shí)間:2021年11月16日 11:25:31   作者:這樣不好吧!  
這篇文章主要介紹了Springboot中用 Netty 開(kāi)啟UDP服務(wù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Netty

Netty是一種提供網(wǎng)絡(luò)編程的工具,是對(duì)socket編程的一例優(yōu)秀的包裝,支持TCP、UDP、FTP等協(xié)議。我們可以用Netty開(kāi)發(fā)自己的http服務(wù)器、udp服務(wù)器、FTP服務(wù)器,RPC服務(wù)器等

Netty大受歡迎的原因:

  • 并發(fā)高

Netty支持NIO編程,NIO的持支,可以大大提升并發(fā)性能。

  • 傳輸快

Netty NIO的一個(gè)特性是零拷貝,直接在內(nèi)存中開(kāi)辟一塊,剩去了socket緩沖區(qū),

  • 封裝好

接下來(lái)寫(xiě)一個(gè)簡(jiǎn)單的udp demo。大體思路:

  • 寫(xiě)一個(gè)netty的 基于UDP的Server 用來(lái)接受數(shù)據(jù)
  • 寫(xiě)個(gè)一處理類,用于對(duì)接受的數(shù)據(jù)進(jìn)行處理,然后返回信息

新建一個(gè)springboot項(xiàng)目。在pom中引入jar

pom.xml

        
       <!--springboot version 我用的是2.1.3.RELEASE-->
		 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
       
       <!--web模塊的啟動(dòng)器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- netty依賴 springboot2.x自動(dòng)導(dǎo)入版本 -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
        </dependency>
        
		<!-- 這里我用到了@slf4j 所以引入這個(gè)jar -->
      <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

創(chuàng)建NettyUDPServer

Channel 通道的類型

  • NioSocketChannel, 代表異步的客戶端 TCP Socket 連接.
  • NioServerSocketChannel, 異步的服務(wù)器端 TCP Socket 連接.
  • NioDatagramChannel, 異步的 UDP 連接
  • NioSctpChannel, 異步的客戶端 Sctp 連接.
  • NioSctpServerChannel, 異步的 Sctp 服務(wù)器端連接.
  • OioSocketChannel, 同步的客戶端 TCP Socket 連接.
  • OioServerSocketChannel, 同步的服務(wù)器端 TCP Socket 連接.
  • OioDatagramChannel, 同步的 UDP 連接
  • OioSctpChannel, 同步的 Sctp 服務(wù)器端連接.
  • OioSctpServerChannel, 同步的客戶端 TCP Socket 連接.

Bootstrap 是 Netty 提供的一個(gè)便利的工廠類,可以通過(guò)它來(lái)完成 Netty 的客戶端或服務(wù)器端的 Netty 初始化。

package com.demo.udpdemo.UDPServer;
import com.demo.udpdemo.handler.BootNettyUdpSimpleChannelInboundHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import lombok.extern.slf4j.Slf4j;
/**
 * @author 
 */
@Slf4j
public class BootNettyUdpServer {
    /**
     * 啟動(dòng)服務(wù)
     */
    public void bind(int port) {
        log.info("-------------------------------udpServer-------------------------");
        //表示服務(wù)器連接監(jiān)聽(tīng)線程組,專門(mén)接受 accept 新的客戶端client 連接
        EventLoopGroup bossLoopGroup  = new NioEventLoopGroup();
        try {
            //1,創(chuàng)建netty bootstrap 啟動(dòng)類
            Bootstrap serverBootstrap = new Bootstrap();
            //2、設(shè)置boostrap 的eventLoopGroup線程組
            serverBootstrap = serverBootstrap.group(bossLoopGroup);
            //3、設(shè)置NIO UDP連接通道
            serverBootstrap = serverBootstrap.channel(NioDatagramChannel.class);
            //4、設(shè)置通道參數(shù) SO_BROADCAST廣播形式
            serverBootstrap = serverBootstrap.option(ChannelOption.SO_BROADCAST, true);
            //5、設(shè)置處理類 裝配流水線
            serverBootstrap = serverBootstrap.handler(new BootNettyUdpSimpleChannelInboundHandler());
            //6、綁定server,通過(guò)調(diào)用sync()方法異步阻塞,直到綁定成功
            ChannelFuture f = serverBootstrap.bind(port).sync();
            log.info(BootNettyUdpServer.class.getName()+" started and listend on "+f.channel().localAddress());
            //7、監(jiān)聽(tīng)通道關(guān)閉事件,應(yīng)用程序會(huì)一直等待,直到channel關(guān)閉
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            System.out.println("netty udp close!");
            //8 關(guān)閉EventLoopGroup,
            bossLoopGroup.shutdownGracefully();
        }
    }
}

NettyUdpSimpleChannelInboundHandler

package com.demo.udpdemo.handler;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
/**
 * @author 
 */
@Slf4j
public class BootNettyUdpSimpleChannelInboundHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
        try {
            String strdata = msg.content().toString(CharsetUtil.UTF_8);
            //打印收到的消息
            log.info("---------------------receive data--------------------------");
            log.info(strdata);
            log.info("---------------------receive data--------------------------");
            //收到udp消息后,可通過(guò)此方式原路返回的方式返回消息,例如返回時(shí)間戳
            ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("ok", CharsetUtil.UTF_8), msg.sender()));
        } catch (Exception e) {
        }
    }
}

修改啟動(dòng)類,啟動(dòng)執(zhí)行UDPServer.bind方法,啟動(dòng)udpServer

@SpringBootApplication
@EnableAsync
public class UdpDemoApplication implements CommandLineRunner {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(UdpDemoApplication.class);
        app.run(args);
    }
    @Async
    @Override
    public void run(String... args){
       new BootNettyUdpServer().bind(51000);
    }
}

test

在test類下面,新建一個(gè)test方法

sendUdpRequestTest

  //定義客戶端ip
  private static final String SERVER_HOSTNAME = "127.0.0.1";
    // 服務(wù)器端口
    private static final int SERVER_PORT = 51000;
    // 本地發(fā)送端口
    private static final int LOCAL_PORT = 8888;
 @Test
    public void sendUdpRequestTest() {
        try {
            // 1,創(chuàng)建udp服務(wù)。通過(guò)DatagramSocket對(duì)象。
            DatagramSocket socket = new DatagramSocket(LOCAL_PORT);
            // 2,確定數(shù)據(jù),并封裝成數(shù)據(jù)包。DatagramPacket(byte[] buf, int length, InetAddress
            // address, int port)
            byte[] buf = "hello".getBytes();
            DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName(SERVER_HOSTNAME),
                    SERVER_PORT);
            // 3,通過(guò)socket服務(wù),將已有的數(shù)據(jù)包發(fā)送出去。通過(guò)send方法。
            socket.send(dp);
            // 4,關(guān)閉資源。
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

結(jié)果

2021-09-03 13:14:47.912 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:14:47.912 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : 你好,世界
2021-09-03 13:14:47.912 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:16:11.748 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:16:11.748 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : 你好,世界
2021-09-03 13:16:11.748 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:17:11.664 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:17:11.664 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : hello
2021-09-03 13:17:11.664 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:17:32.714 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:17:32.714 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : hello
2021-09-03 13:17:32.714 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java 中堆內(nèi)存和棧內(nèi)存理解

    java 中堆內(nèi)存和棧內(nèi)存理解

    這篇文章主要介紹了java 中的堆內(nèi)存和棧內(nèi)存的知識(shí),有需要的朋友可以參考下
    2017-03-03
  • java ssm框架實(shí)現(xiàn)分頁(yè)功能的示例代碼(oracle)

    java ssm框架實(shí)現(xiàn)分頁(yè)功能的示例代碼(oracle)

    這篇文章主要介紹了java ssm框架實(shí)現(xiàn)分頁(yè)功能的示例代碼(oracle),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • JSP頁(yè)面?zhèn)鲄⒊霈F(xiàn)中文亂碼的解決方案

    JSP頁(yè)面?zhèn)鲄⒊霈F(xiàn)中文亂碼的解決方案

    這篇文章主要介紹了JSP頁(yè)面?zhèn)鲄⒊霈F(xiàn)中文亂碼的解決方案,非常實(shí)用,需要的朋友可以參考下
    2014-08-08
  • java中獲取類加載路徑和項(xiàng)目根路徑的5種方式分析

    java中獲取類加載路徑和項(xiàng)目根路徑的5種方式分析

    本篇文章介紹了,java中獲取類加載路徑和項(xiàng)目根路徑的5種方式分析。需要的朋友參考下
    2013-05-05
  • SpringBoot任務(wù)之詳解郵件任務(wù)

    SpringBoot任務(wù)之詳解郵件任務(wù)

    今天給大家整理的文章是SpringBoot郵件任務(wù)的相關(guān)知識(shí)點(diǎn),文中有非常詳細(xì)的介紹及代碼示例,對(duì)正在學(xué)習(xí)SpringBoot任務(wù)的小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • Java實(shí)現(xiàn)基于token認(rèn)證的方法示例

    Java實(shí)現(xiàn)基于token認(rèn)證的方法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)基于token認(rèn)證的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java解析XML文件開(kāi)源庫(kù)DOM4J

    Java解析XML文件開(kāi)源庫(kù)DOM4J

    dom4j是一個(gè)Java的XML API,是jdom的升級(jí)品,用來(lái)讀寫(xiě)XML文件的。dom4j是一個(gè)十分優(yōu)秀的JavaXML API,具有性能優(yōu)異、功能強(qiáng)大和極其易使用的特點(diǎn),它的性能超過(guò)sun公司官方的dom技術(shù),同時(shí)它也是一個(gè)開(kāi)放源代碼的軟件
    2023-01-01
  • Java中Redis的布隆過(guò)濾器詳解

    Java中Redis的布隆過(guò)濾器詳解

    這篇文章主要介紹了Java中Redis的布隆過(guò)濾器詳解,我們經(jīng)常會(huì)把一部分?jǐn)?shù)據(jù)放在Redis等緩存,比如產(chǎn)品詳情,這樣有查詢請(qǐng)求進(jìn)來(lái),我們可以根據(jù)產(chǎn)品Id直接去緩存中取數(shù)據(jù),而不用讀取數(shù)據(jù)庫(kù),這是提升性能最簡(jiǎn)單,最普遍,也是最有效的做法,需要的朋友可以參考下
    2023-09-09
  • 冒泡排序的原理及java代碼實(shí)現(xiàn)

    冒泡排序的原理及java代碼實(shí)現(xiàn)

    冒泡排序法:關(guān)鍵字較小的記錄好比氣泡逐趟上浮,關(guān)鍵字較大的記錄好比石塊下沉,每趟有一塊最大的石塊沉底。算法本質(zhì):(最大值是關(guān)鍵點(diǎn),肯定放到最后了,如此循環(huán))每次都從第一位向后滾動(dòng)比較,使最大值沉底,最小值上升一次,最后一位向前推進(jìn)
    2016-02-02
  • SpringBoot整合Kaptcha實(shí)現(xiàn)圖形驗(yàn)證碼功能

    SpringBoot整合Kaptcha實(shí)現(xiàn)圖形驗(yàn)證碼功能

    這篇文章主要介紹了SpringBoot整合Kaptcha實(shí)現(xiàn)圖形驗(yàn)證碼功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09

最新評(píng)論