1. 程式人生 > >Netty實戰(1)使用Netty搭建一個簡單的客戶端與伺服器的互動Demo

Netty實戰(1)使用Netty搭建一個簡單的客戶端與伺服器的互動Demo

       Netty 是一個基於 JAVA NIO 類庫的非同步通訊框架,它的架構特點是:非同步非阻塞、基於事件驅動、高效能、高可靠性和高可定製性。換句話說,Netty是一個NIO框架,使用它可以簡單快速地開發網路應用程式,比如客戶端和服務端的協議。Netty大大簡化了網路程式的開發過程比如TCP和UDP的 Socket的開發。Netty 已逐漸成為 Java NIO 程式設計的首選框架。

一. Netty 的優點:

  • API 使用簡單,開發門檻低;
  • 功能強大,預置了多種編解碼功能,支援多種主流協議;
  • 定製能力強,可以通過 ChannelHandler 對通訊框架進行靈活的擴充套件;
  • 效能高,通過與其它業界主流的 NIO 框架對比,Netty 的綜合性能最優;
  • 社群活躍,版本迭代週期短,發現的 BUG 可以被及時修復,同時,更多的新功能會被加入;
  • 經歷了大規模的商業應用考驗,質量得到驗證。在網際網路、大資料、網路遊戲、企業應用、電信軟體等眾多行業得到成功商用,證明了它完全滿足不同行業的商用標準。

二、搭建Netty的一個簡單應用

(1)新增Maven依賴  pom.xml檔案   主要是新增netty的依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.netty</groupId>
    <artifactId>telnetDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.0.36.Final</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

(2)SimpleServer(服務端)

package com;

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;

/**
 *
 * Netty中,通訊的雙方建立連線後,會把資料按照ByteBuf的方式進行傳輸,
 * 例如http協議中,就是通過HttpRequestDecoder對ByteBuf資料流進行處理,轉換成http的物件。
 *
 */
public class SimpleServer {
    private int port;

    public SimpleServer(int port) {
        this.port = port;
    }

    public void run() throws Exception {
        //EventLoopGroup是用來處理IO操作的多執行緒事件迴圈器
        //bossGroup 用來接收進來的連線
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //workerGroup 用來處理已經被接收的連線
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //啟動 NIO 服務的輔助啟動類
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    //配置 Channel
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            // 註冊handler
                            ch.pipeline().addLast(new SimpleServerHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            // 繫結埠,開始接收進來的連線
            ChannelFuture f = b.bind(port).sync();
            // 等待伺服器 socket 關閉 。
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        new SimpleServer(9999).run();
    }
}

(3)SimpleServerHandler(服務端請求處理Handler)

package com;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class SimpleServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("SimpleServerHandler.channelRead");
        ByteBuf result = (ByteBuf) msg;
        byte[] result1 = new byte[result.readableBytes()];
        // msg中儲存的是ByteBuf型別的資料,把資料讀取到byte[]中
        result.readBytes(result1);
        String resultStr = new String(result1);
        // 接收並列印客戶端的資訊
        System.out.println("Client said:" + resultStr);
        // 釋放資源,這行很關鍵
        result.release();

        // 向客戶端傳送訊息
        String response = "hello client!";
        // 在當前場景下,傳送的資料必須轉換成ByteBuf陣列
        ByteBuf encoded = ctx.alloc().buffer(4 * response.length());
        encoded.writeBytes(response.getBytes());
        ctx.write(encoded);
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 當出現異常就關閉連線
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

}

(4)SimpleClient(客戶端)

package com;

import io.netty.bootstrap.Bootstrap;
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;
import io.netty.channel.socket.nio.NioSocketChannel;

public class SimpleClient {

    public void connect(String host, int port) throws Exception {
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            Bootstrap b = new Bootstrap();
            b.group(workerGroup);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new SimpleClientHandler());
                }
            });

            // Start the client.
            ChannelFuture f = b.connect(host, port).sync();

            // Wait until the connection is closed.
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        SimpleClient client=new SimpleClient();
        client.connect("127.0.0.1", 9999);
    }

}

(5)SimpleClientHandler(客戶端請求處理Handler)

package com;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class SimpleClientHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("SimpleClientHandler.channelRead");
        ByteBuf result = (ByteBuf) msg;
        byte[] result1 = new byte[result.readableBytes()];
        result.readBytes(result1);
        System.out.println("Server said:" + new String(result1));
        result.release();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 當出現異常就關閉連線
        cause.printStackTrace();
        ctx.close();
    }


    // 連線成功後,向server傳送訊息
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String msg = "hello Server!";
        ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());
        encoded.writeBytes(msg.getBytes());
        ctx.write(encoded);
        ctx.flush();
    }
}

相關推薦

python--DenyHttp項目1--socket編程:客戶服務器

brush accept acc -- highlight 發送消息 src size 接受 查找了許多資料,實現了客戶端與服務器端的連接,通過虛擬機進行測試 服務器端IP:192.168.37.129 端口1122 客戶端IP:  192.168.37.1 端口1122

Mina學習1:mina實現簡單服務客戶

mina是一個基於javaNio網路通訊應用框架,使用mina可以輕鬆的搭建伺服器,接下來將使用mina搭建一個小型的服務端 原始碼–MinaServer.java package serv

Netty實戰1使用Netty搭建一個簡單客戶伺服器互動Demo

       Netty 是一個基於 JAVA NIO 類庫的非同步通訊框架,它的架構特點是:非同步非阻塞、基於事件驅動、高效能、高可靠性和高可定製性。換句話說,Netty是一個NIO框架,使用它可以簡單快速地開發網路應用程式,比如客戶端和服務端的協議。Netty大大簡化了網

掃盲貼如何搭建一個簡單的本地PHP伺服器-WAMP基礎指南

在除錯WEB應用程式時,我們都需要很多配置,LAMP,ASP,IIS等等。而在所有方式中,最簡單的莫過於WAMP了。 WAMP是Windows下的Apache+Mysql+PHP的縮寫。 通過這個伺服器我們可以完全傻瓜的在一般的Windows PC上面搭建起一個WEB伺服器

Netty學習1:Channel的概念

1. Channel Channel是Netty的核心概念之一,它是Netty網路通訊的主體,由它負責同對端進行網路通訊、註冊和資料操作等功能。 1.1 工作原理 如上圖所示: 一旦使用者端連線成功,將新建一個channel同該使用者端進行繫結 channel從EventL

Netty入門環境搭建及使用

一、專案建立   在 Eclipse 中右鍵,新建->專案->Maven->Maven Project->下一步->選擇 quickstart      下一步->設定如圖(引數自取)      點選完成。    專案會自動建立

深度學習之PyTorch實戰1——基礎學習及搭建環境

  最近在學習PyTorch框架,買了一本《深度學習之PyTorch實戰計算機視覺》,從學習開始,小編會整理學習筆記,並部落格記錄,希望自己好好學完這本書,最後能熟練應用此框架。   PyTorch是美國網際網路巨頭Facebook在深度學習框架Torch的基礎上使用Python重寫的一個全新的深度學習框架,

Scala學習筆記9—— Scala實戰專案1- 環境搭建

1 專案需求 1.1 資料庫管理(java實現) default my-db1 my-db2 id:資料庫編號 name : 資料庫名稱 location : 資料庫存放在 HDFS/S3/OSS 等檔案系統上的目錄 /user/hive/warehouse /user/

Netty學習總結1——Netty入門介紹

1.Netty是什麼? Netty是一個基於JAVA NIO類庫的非同步通訊框架,它的架構特點是:非同步非阻塞、基於事件驅動、高效能、高可靠性和高可定製性。 2.使用Netty能夠做什麼?

webpack3實戰1打包一個CDN引入的jQuery專案

前注: 如果可以,請給本專案加【Star】和【Fork】持續關注。 有疑義請點選這裡,發【Issues】。 1、需求列表 1、在html檔案裡,通過CDN引入了jQuery; 2、步驟 安裝依賴 npm install html檔案中引入

Hadoop實戰1_阿里雲搭建Hadoop2.x的偽分散式環境

環境:阿里雲伺服器 CentOS 7 x86_64 安裝介質:jdk-7u75-linux-i586.tar.gz,hadoop-2.4.1.tar.gz 安裝jdk tar -zxvf jdk-7u75-linux-i586.tar.gz 配置

Docker 實戰1- 使用 Jenkins 映象建立容器,並搭建 Python + Pytest +Allure 的自動化測試環境

如果你還想從頭學起 Docker,可以看看這個系列的文章哦! https://www.cnblogs.com/poloyy/category/1870863.html   安裝 Docker 直接參考我這篇文章哦:https://www.cnblogs.com/poloyy/p/13921450.h

ceph分布式存儲實戰1——ceph集群測試主機規劃

monit dep release host eas rst 存儲 實戰 hostname 主機規劃節點磁盤(4塊)網卡(2塊)mem/cpuOSHostName節點1os-ceph-node1/10G私Eth0:dhcp1G/1CentOS Linux release

Spring實戰1

手動 之前 ava singleton 標簽 測試 之間 解決 業務邏輯 本博客是參考Spring實戰第四版,對其中重要的知識點進行總結。 Spring是如何簡化java開發的? 答:(1)基於POJO的輕量級和最小侵入性編程;(2)通過依賴註入和面向接口來松耦合;

python+selenium1--環境搭建

重新 一個 輸入 3.x 成了 ade pytho 復習 安裝 做自動化也很長時間了,這段時間項目初期沒什麽事情幹就在復習以前做過的seleniu+python的知識,現在想做一個簡單的記錄,也對自己學習有一個驅動作用吧。 以上。 一、python下載地址: https

靈活強大的MySQL代理中間件ProxySQL應用實戰1

sys www 流量 均可 rpm -ivh 硬盤 代理 發的 table 一、常見的Mysql中間件介紹 很多人都會把中間件認為是讀寫分離,其實讀寫分離只是中間件可以提供的一種功能,最主要的功能還是在於他可以分庫分表。下面介紹下常見的開源mysql中間件。 DBProx

ServiceComb實戰 1org.springframework.web.HttpMediaTypeNotSupportedException

一、異常現象: @Override @PostMapping(path = "logon") public ResponseEntity<Boolean> logon(@RequestBody UserDTO user) { if (validateUs

大資料實戰——環境搭建

設定 hostname 為hadoop: $hostname hadoop 設定ip地址與hostname關聯:$vim /etc/hosts     新增  IP地址 hadoop  關閉 iptables: $service iptabl

springboot實戰1springboot基本配置

1 入口類和@SpringBootApplication package com.wuk.springbootHello; import org.springframework.boot.SpringApplication; import org.springframework.b

ROS串列埠通訊1環境搭建

ROS串列埠通訊(1)環境搭建 引言 1、ubuntu串列埠驅動安裝和使用 1.1 安裝 1.2 使用 1.3 Ubuntu 檢視串列埠,設定串列埠許可權 2、Ubuntu下的串列埠助手cute