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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Netty入门——客户端与服务端通信

發布時間:2024/4/24 综合教程 38 生活家
生活随笔 收集整理的這篇文章主要介紹了 Netty入门——客户端与服务端通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

什么是物聯網?
nio通信框架

物聯網主要運用到netty哪些特性
a、TCP長連接
b、能夠和各種序列化框架完美整合

為什么要使用netty,相對于其他通信框架mina有哪些優點
a、API使用簡單,開發門檻低
b、功能強大,預置了多種編解碼功能,支持多種主流協議
c、社區活躍,版本更新快
d、技術穩定可靠,如:elasticsearch、spark、dubbo、motan等開源框架底層通信采用的是netty

1、Netty服務端編寫
首先,Netty通過ServerBootstrap啟動服務端代碼,需要四步:
第一步,定義兩個線程組,用來處理客戶端通道的accept和讀寫事件
第二步,綁定服務端通道NioServerSocketChannel
第三步,給讀寫事件的線程通道綁定handle,處理具體的業務邏輯
第四步,綁定監聽
1.1、NettyServer——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;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;

/**
 *  Netty服務端編寫
 * 
 * @author Administrator
 *
 */
public class NettyServer {
    
    public static void main(String[] args) throws InterruptedException {
        // 首先,netty通過ServerBootstrap啟動服務端
        ServerBootstrap server = new ServerBootstrap();
        EventLoopGroup parentGroup = new NioEventLoopGroup();
        EventLoopGroup childGroup =new NioEventLoopGroup();
        //第1步定義兩個線程組,用來處理客戶端通道的accept和讀寫事件
        //parentGroup用來處理accept事件,childgroup用來處理通道的讀寫事件
        //parentGroup獲取客戶端連接,連接接收到之后再將連接轉發給childgroup去處理
        server.group(parentGroup, childGroup);
        
        //用于構造服務端套接字ServerSocket對象,標識當服務器請求處理線程全滿時,用于臨時存放已完成三次握手的請求的隊列的最大長度。
        //用來初始化服務端可連接隊列
        //服務端處理客戶端連接請求是按順序處理的,所以同一時間只能處理一個客戶端連接,多個客戶端來的時候,服務端將不能處理的客戶端連接請求放在隊列中等待處理,backlog參數指定了隊列的大小。
        server.option(ChannelOption.SO_BACKLOG, 128);
        
        //第2步綁定服務端通道
        server.channel(NioServerSocketChannel.class);
        
        //第3步綁定handler,處理讀寫事件,ChannelInitializer是給通道初始化
        server.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                 //解碼器,接收的數據進行解碼,一定要加在SimpleServerHandler 的上面
                //maxFrameLength表示這一貞最大的大小 
                //delimiter表示分隔符,我們需要先將分割符寫入到ByteBuf中,然后當做參數傳入;
                //需要注意的是,netty并沒有提供一個DelimiterBasedFrameDecoder對應的編碼器實現(筆者沒有找到),因此在發送端需要自行編碼添加分隔符,如  
分隔符
                ch.pipeline().addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()[0]));
                 //把傳過來的數據 轉換成byteBuf
                ch.pipeline().addLast(new SimpleServerHandler());
            }
        });
        
        //第4步綁定8080端口
        ChannelFuture future = server.bind(8080).sync();
        //當通道關閉了,就繼續往下走
        future.channel().closeFuture().sync();
    }

}

1.2、SimpleServerHandler——處理客戶端返回的數據

import java.nio.charset.Charset;

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

/**
 * 處理客戶端返回的數據
 * 
 * @author Administrator
 *
 */
public class SimpleServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * 讀取客戶端通道的數據
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //可以在這里面寫一套類似SpringMVC的框架
        //讓SimpleServerHandler不跟任何業務有關,可以封裝一套框架
        if(msg instanceof ByteBuf){
            System.out.println(((ByteBuf)msg).toString(Charset.defaultCharset()));
        }
        
        //業務邏輯代碼處理框架。。。
        
        //返回給客戶端的數據,告訴我已經讀到你的數據了
        String result = "hello client ";
        ByteBuf buf = Unpooled.buffer();
        buf.writeBytes(result.getBytes());
        ctx.channel().writeAndFlush(buf);
        
        ByteBuf buf2 = Unpooled.buffer();
        buf2.writeBytes("
".getBytes());
        ctx.channel().writeAndFlush(buf2);
        System.out.println("==========");
    }
 
}

//使用下面命令測試上面代碼。
1.開啟上面main方法。
2.執行一下命令
c:>telnet localhost 8080
隨便輸入,會發現eclipse控制臺會監聽到輸入的內容,有個問題接收時一個字一個字接受,可以讓他一行一行接收

2、netty客戶端編寫
第一步,連接到服務端
第二步,向服務端發送數據
第三步,處理服務端返回的數據
第四步,關閉連接
2.1、NettyClient——Netty客戶端編寫

import com.alibaba.fastjson.JSONObject;
import com.dxfx.user.model.User;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.AttributeKey;

/**
 * Netty客戶端編寫
 * @author Administrator
 *
 */
public class NettyClient {
    
    public static void main(String[] args) throws InterruptedException {
        // 首先,netty通過ServerBootstrap啟動服務端
        Bootstrap client = new Bootstrap();
        
        //第1步 定義線程組,處理讀寫和鏈接事件,沒有了accept事件
        EventLoopGroup group = new NioEventLoopGroup();
        client.group(group );
        
        //第2步 綁定客戶端通道
        client.channel(NioSocketChannel.class);
        
        //第3步 給NIoSocketChannel初始化handler, 處理讀寫事件
        client.handler(new ChannelInitializer<NioSocketChannel>() {  //通道是NioSocketChannel
            @Override
            protected void initChannel(NioSocketChannel ch) throws Exception {
                //字符串編碼器,一定要加在SimpleClientHandler 的上面
                ch.pipeline().addLast(new StringEncoder());
                ch.pipeline().addLast(new DelimiterBasedFrameDecoder(   
                        Integer.MAX_VALUE, Delimiters.lineDelimiter()[0])); 
                //找到他的管道 增加他的handler
                ch.pipeline().addLast(new SimpleClientHandler());
            }
        });
        
        //連接服務器
        ChannelFuture future = client.connect("localhost", 8080).sync();
        
        //發送數據給服務器
        User user = new User();
        user.setAge(12);
        user.setId(1);
        user.setName("sssss");
        future.channel().writeAndFlush(JSONObject.toJSONString(user)+"
");
        
        for(int i=0;i<5;i++){
            String msg = "ssss"+i+"
";
            future.channel().writeAndFlush(msg);
        }
        
        //當通道關閉了,就繼續往下走
        future.channel().closeFuture().sync();
        
        //接收服務端返回的數據
        AttributeKey<String> key = AttributeKey.valueOf("ServerData");
        Object result = future.channel().attr(key).get();
        System.out.println(result.toString());
    }

}

2.2、SimpleClientHandler——處理服務端返回的數據

import java.nio.charset.Charset;

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

/**
 * 處理服務端返回的數據
 * 
 * @author Administrator
 *
 */
public class SimpleClientHandler extends ChannelInboundHandlerAdapter {
 
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof ByteBuf) {
            String value = ((ByteBuf) msg).toString(Charset.defaultCharset());
            System.out.println("服務器端返回的數據:" + value);
        }
         
        AttributeKey<String> key = AttributeKey.valueOf("ServerData");
        ctx.channel().attr(key).set("客戶端處理完畢");

        //把客戶端的通道關閉
        ctx.channel().close();
    }

}

3、netty服務端輸出的信息

{"age":12,"id":1,"name":"sssss"}
==========
ssss0
==========
ssss1
==========
ssss2
==========
ssss3
==========
ssss4
==========

4、netty客戶端輸出的信息

服務器端返回的數據:hello client 
客戶端處理完畢
服務器端返回的數據:hello client 
服務器端返回的數據:hello client 
服務器端返回的數據:hello client 
服務器端返回的數據:hello client 
服務器端返回的數據:hello client 

總結

以上是生活随笔為你收集整理的Netty入门——客户端与服务端通信的全部內容,希望文章能夠幫你解決所遇到的問題。

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