Netty-Hello-World(一)

Netty简介

Netty是一个NIO client-server框架,使用Netty可以快速开发网络应用,例如服务器和客户端协议。Netty提供了一种新的方式来开发网络应用程序,这种新的方式使得它容易使用和有很强的扩展性。Netty的内部实现很复杂,但是Netty提供了简单易用的api从网络处理代码中解耦业务逻辑。Netty是完全基于NIO实现,所以整个Netty都是异步的。网络应用程序通常需要有较高的可扩展性,无论是Netty还是其他的基于Java NIO的框架,都会提供可扩展的解决方案。Netty中一个关键的组成部分是它的异步特性。

Netty架构组成

Hello World

回顾NIO通信步骤:

  1. 创建ServerSocketChannel,为他配置非阻塞模式。
  2. 绑定监听,配置TCP参数,录入backlog大小等。
  3. 创建一个独立的IO线程,用于轮询多路复用器Selector。
  4. 创建Selector,将之前的ServletSocketChannel注册到Selector上,并配置监听标识位SelectionKey.ACCEPT。
  5. 启动IO线程,在循环体中执行Selector.select()方法,轮询就绪的通道。
  6. 当轮询到处于就绪的通道时,需要进行判断操作位,如果是ACCEPT状态,说明是新的客户端接入,则调用accept方法接受新的客户端。
  7. 设置新接入客户端的一些参数,如非阻塞,并将其通道继续注册到Selector之中,设置监听标识位等。
  8. 如果轮询的通道操作位是READ,则进行读取,构造Buffer对象等。
  9. 更细节的还有数据没发送完成继续发送的问题…

一个简单的NIO服务端程序就是如此复杂,我们来看看Netty完成这件事情需要的步骤。Netty实现通信的步骤:

  1. 创建两个NIO线程组,一个专门用于网络时间处理(接受客户端的连接),另一个则进行网络通信的读写。
  2. 创建一个ServerBootstrap对象,配置Netty的一系列参数,例如接受传出数据的缓存大小等待。
  3. 创建一个实际处理数据的类ChannelInitializer,进行初始化的准备工作,比如设置接受传出数据的字符集、格式、已经实际处理数据的接口。
  4. 绑定端口,执行同步阻塞方法等待服务器启动即可。
public class Server {

	public static void main(String[] args) throws InterruptedException {
		//1.第一个线程组是用于接收Client连接的
		EventLoopGroup bossGroup = new NioEventLoopGroup(); 
		//2.第二个线程组是用于实际的业务处理操作的
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		//3.声明一个启动NIO服务的辅助启动类,就是对我们的Server端进行一系列的配置
		ServerBootstrap b = new ServerBootstrap();
		//将两个工作线程组加入ServerBootstrap
		b.group(bossGroup, workerGroup)
		//使用NioServerSocketChannel这种类型的通道
		.channel(NioServerSocketChannel.class)
		//一定要使用childHandler绑定具体的时间处理器
		.childHandler(new ChannelInitializer<SocketChannel>() {
			@Override
			protected void initChannel(SocketChannel sc) throws Exception {
				sc.pipeline().addLast(new ServerHandler());
			}
		})
		//设置指定通道实现的配置参数,也就是设置tcp缓冲区
		.option(ChannelOption.SO_BACKLOG, 128)
		//保持连接
		.option(ChannelOption.SO_KEEPALIVE, true);

		//绑定指定端口,进行监听
		ChannelFuture f = b.bind(8765).sync();
		
		//Thread.sleep(Integer.MAX_VALUE);
		f.channel().closeFuture().sync();
		
		bossGroup.shutdownGracefully();
		workerGroup.shutdownGracefully();
	}
}
public class ServerHandler extends ChannelHandlerAdapter{

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		//((ByteBuf) msg).release();
		try{
			// do something msf
			ByteBuf buf = (ByteBuf) msg;
			byte[] data = new byte[buf.readableBytes()];
			buf.readBytes(data);
			String request = new String(data,"utf-8");
			System.out.println("Server: " + request);
			
		} finally {
			ReferenceCountUtil.release(msg);
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		 cause.printStackTrace();
		 ctx.close();
	}
}
public class Client {

	public static void main(String[] args) throws InterruptedException {
		EventLoopGroup workgroup = new NioEventLoopGroup();
		Bootstrap b = new Bootstrap();
		b.group(workgroup)
		.channel(NioSocketChannel.class)
		.handler(new ChannelInitializer<SocketChannel>() {
			@Override
			protected void initChannel(SocketChannel sc) throws Exception {
				sc.pipeline().addLast(new ClientHandler());
			}
		});
		
		ChannelFuture cf = b.connect("127.0.0.1", 8765).sync();
		
		//向服务端写数据
		cf.channel().write(Unpooled.copiedBuffer("hell world".getBytes()));
		cf.channel().flush();
		
		cf.channel().closeFuture().sync();
		workgroup.shutdownGracefully();
	}
}
public class ClientHandler extends ChannelHandlerAdapter{

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		((ByteBuf) msg).release();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		 cause.printStackTrace();
		 ctx.close();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用Netty搭建TCP服务器的示例代码(Hello World): ```java import io.netty.bootstrap.ServerBootstrap; 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.NioServerSocketChannel; public class HelloWorldServer { private final int port; public HelloWorldServer(int port) { this.port = port; } public void run() throws Exception { // 创建两个 EventLoopGroup,一个用于接收客户端连接,一个用于处理客户端请求 EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { // 创建 ServerBootstrap 对象,用于配置服务器 ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { // 添加消息处理器 ch.pipeline().addLast(new HelloWorldServerHandler()); } }); // 绑定端口,开始接收客户端请求 ChannelFuture f = b.bind(port).sync(); // 等待服务器 socket 关闭 f.channel().closeFuture().sync(); } finally { // 释放资源 workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; new HelloWorldServer(port).run(); } } ``` 其中,`HelloWorldServerHandler` 是自定义的消息处理器,可以根据需要进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值