Netty入門(hello world)

1、Netty簡介

   Netty是由JBOSS提供的一個java開源網絡通訊框架。Netty是基於Java NIO client-server的網絡應用框架,使用Netty可以快速開發網絡應用,例如服務器和客戶端協議。Netty提供了一種新的方式來開發網絡應用程序,這種新的方式使它很容易使用和具有很強的擴展性。Netty的內部實現是很複雜的,但是Netty提供了簡單易用的API從網絡處理代碼中解耦業務邏輯。Netty是完全基於NIO實現的,所以整個Netty都是異步的。

    netty的優點

        它的健壯性、功能、性能、可定製性和可擴展性在同類框架都是首屈一指的。它已經得到成百上千的商業/商用項目驗證,如Hadoop的RPC框架Avro、RocketMQ以及主流的分佈式通信框架Dubbox等等。

2、Hello World 入門

    1、Netty通信的步驟:

        ①創建兩個NIO線程組,一個專門用於網絡事件處理(接受客戶端的連接),另一個則進行網絡通信的讀寫。

        ②創建一個ServerBootstrap對象,配置Netty的一系列參數,例如接受傳出數據的緩存大小等。

        ③創建一個用於實際處理數據的類ChannelInitializer,進行初始化的準備工作,比如設置接受傳出數據的字符集、格式以及實際處理數據的接口。

        ④綁定端口,執行同步阻塞方法等待服務器端啓動即可。

    2、入門實例(以helloworld爲例)

    2.1下載相應的jar包 

        可以去http://netty.io/上下載所需的Netty包

        我所用的jar包爲 https://pan.baidu.com/s/1tm2EgYtDpTS5dejVnHhvPw 密碼:vc8b

    2.2 代碼實現

        服務器端     

package com.xyq.netty.hello;

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;

public class Server {

	public static void main(String[] args) throws Exception {
		
		//1 創建兩個線程組 
		EventLoopGroup pGroup = new NioEventLoopGroup();//一個是用於處理服務器端接收客戶端連接的
		EventLoopGroup cGroup = new NioEventLoopGroup();//一個是進行網絡通信的(網絡讀寫的)
		
		//2 創建輔助工具類,用於服務器通道的一系列配置
		ServerBootstrap bootstrap = new ServerBootstrap();
		bootstrap.group(pGroup, cGroup)//綁定倆個線程組
		.channel(NioServerSocketChannel.class)//指定NIO的模式
		.option(ChannelOption.SO_BACKLOG, 1024)//設置tcp緩衝區
		.option(ChannelOption.SO_SNDBUF, 32*1024)//設置發送緩衝大小
		.option(ChannelOption.SO_RCVBUF, 32*1024)//設置接收緩衝大小
		.option(ChannelOption.SO_KEEPALIVE, true)//保持連接
		.childHandler(new ChannelInitializer<SocketChannel>() {

			@Override
			protected void initChannel(SocketChannel ch) throws Exception {
				
				//3 在這裏配置具體數據接收方法的處理
				ch.pipeline().addLast(new ServerHandler());
			}
		});
		
		//4 進行綁定
		ChannelFuture cf = bootstrap.bind(8765).sync();
		System.out.println("server start ...");
		
		//5 等待關閉
		cf.channel().closeFuture().sync();
		pGroup.shutdownGracefully();
		cGroup.shutdownGracefully();
	}

}

        服務器管理類

package com.xyq.netty.hello;

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

public class ServerHandler extends ChannelHandlerAdapter {
	
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		
		//讀取客戶端發過來的信息
		ByteBuf buf = (ByteBuf) msg;
		byte[] bs = new byte[buf.readableBytes()];
		buf.readBytes(bs);
		String body = new String(bs, "utf-8");
		System.out.println("server 接收到的數據爲 " + body);
		
		//給客戶端迴應信息
		String result = "server 已經接收到信息, 信息爲 " + body;
		ctx.writeAndFlush(Unpooled.copiedBuffer(result.getBytes()));
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		ctx.close();
	}
}

        客戶端

package com.xyq.netty.hello;

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

public class Client {

	public static void main(String[] args)throws Exception {
		
		//1 創建線程組 
		EventLoopGroup group = new NioEventLoopGroup();
		
		//2 創建輔助工具類,用於服務器通道的一系列配置
		Bootstrap bootstrap = new Bootstrap();
		bootstrap.group(group)//綁定線程組
		.channel(NioSocketChannel.class)//指定NIO的模式
		.handler(new ChannelInitializer<SocketChannel>() {

			@Override
			protected void initChannel(SocketChannel ch) throws Exception {
				
				//3 在這裏配置具體數據接收方法的處理
				ch.pipeline().addLast(new ClientHandler());
			}
		});
		
		//4 進行連接
		ChannelFuture future = bootstrap.connect("127.0.0.1", 8765).sync();
		System.out.println("Client connect....");
		
		//5發送信息
		future.channel().writeAndFlush(Unpooled.copiedBuffer("你好".getBytes()));
		Thread.sleep(1000);
		future.channel().writeAndFlush(Unpooled.copiedBuffer("世界".getBytes()));
		Thread.sleep(1000);
		future.channel().writeAndFlush(Unpooled.copiedBuffer("!".getBytes()));
		
		//6等待關閉
		future.channel().closeFuture().sync();
		group.shutdownGracefully();
	}

}

        客戶端管理類

package com.xyq.netty.hello;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;

public class ClientHandler extends ChannelHandlerAdapter{
	
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		
		try {
			//讀取服務器端發過來的信息
			ByteBuf buf = (ByteBuf) msg;
			byte[] bs = new byte[buf.readableBytes()];
			buf.readBytes(bs);
			String body = new String(bs, "utf-8");
			System.out.println("客戶端接收到服務端的響應消息 " + body);
		} finally{
			ReferenceCountUtil.release(msg);
		}
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		ctx.close();
	}
}
發佈了33 篇原創文章 · 獲贊 15 · 訪問量 9818
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章