NETTY4 简单的 服务端 实现

1.创建服务端启动类 HelloWorldServer 

package com.xw.server;

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.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.net.InetSocketAddress;

import com.xw.server.handler.HelloWorldServerHandler;

public class HelloWorldServer {

	private int port;

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

	public void start() {
		EventLoopGroup bossGroup = new NioEventLoopGroup(1);
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			//创建服务器引导程序实例
			ServerBootstrap sbs = new ServerBootstrap();
					sbs.group(bossGroup, workerGroup)
					//指定 NIO transport  指定端口
					.channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))
					//向通道管道中添加处理程序
					.childHandler(new ChannelInitializer<SocketChannel>() {

						protected void initChannel(SocketChannel ch) throws Exception {
//                            ch.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
							//使用netty的 字符编码解码
							ch.pipeline().addLast("decoder", new StringDecoder());
							ch.pipeline().addLast("encoder", new StringEncoder());
							//通道添加 输入的处理类
							ch.pipeline().addLast(new HelloWorldServerHandler());
						};	

					}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
			// 绑定端口,开始接收进来的连接
			// 绑定服务器、等待服务器关闭并释放资源
			ChannelFuture future = sbs.bind(port).sync();

			System.out.println("Server start listen at " + port);
			//等待服务器套接字关闭。
			future.channel().closeFuture().sync();
		} catch (Exception e) {
			//关闭所有事件循环以终止所有线程。
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}

	public static void main(String[] args) throws Exception {
		int port;
		if (args.length > 0) {
			port = Integer.parseInt(args[0]);
		} else {
			port = 8080;
		}
		new HelloWorldServer(port).start();
	}
}

2.创建输入处理类

package com.xw.server.handler;

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


//为什么在服务器中不使用SimpleChannelInboundHandler呢?因为服务器要返回相同的消息给客户端,在服务器执行完成写操作之前不能释放调
//用读取到的消息,因为写操作是异步的,一旦写操作完成后,Netty中会自动释放消息。
public class HelloWorldServerHandler extends ChannelInboundHandlerAdapter {

	//数据读
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		System.out.println("channelRead");
		System.out.println("channelRead"+ctx.channel().remoteAddress() + "->Server :" + msg.toString());
		//反写客户端
		ctx.write("server back  write" + msg);
		ctx.flush();
	}
	
//	//数据读
//	//如果在 initChannel 中指定了编码解码就直接从MSG中获取 ,如果 没有指定,则可以通过bytebuf读取
//	@Override
//	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//	    ByteBuf buf = (ByteBuf) msg;
//        byte[] req = new byte[buf.readableBytes()];
//        buf.readBytes(req);
//        try {
//            String body = new String(req, "UTF-8");
//            System.out.println("channelRead"+body);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//
//        String response = "server back  write";
//        ByteBuf resp = Unpooled.copiedBuffer(response.getBytes());
//        ctx.write(resp);
//
//	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

		cause.printStackTrace();
		ctx.close();
	}

	@Override
	public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
		System.out.println("channelWritabilityChanged"+ctx.channel().remoteAddress());
	}

	//增加接入时候触发 
	@Override
	public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
		
		
		System.out.println("channelRegistered"+ctx.channel().remoteAddress());
	}

	//关闭通道时候触发 顺序3 
	@Override
	public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
		System.out.println("channelUnregistered"+ctx.channel().remoteAddress());
	}

	//关闭通道时触发 顺序2
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		System.out.println("channelInactive"+ctx.channel().remoteAddress());
	}

	//数据读完
	//关闭通道时候触发  顺序1
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		System.out.println("channelReadComplete"+ctx.channel().remoteAddress());
	}

	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		System.out.println("userEventTriggered"+ctx.channel().remoteAddress());
	}

}

3.测试控制台打印

Server start listen at 8080
channelRegistered/127.0.0.1:52118
channelRegistered/127.0.0.1:52120
channelRead
channelRead/127.0.0.1:52118->Server :1
channelReadComplete/127.0.0.1:52118
channelRead
channelRead/127.0.0.1:52120->Server :2
channelReadComplete/127.0.0.1:52120
channelReadComplete/127.0.0.1:52118
channelInactive/127.0.0.1:52118
channelUnregistered/127.0.0.1:52118
channelReadComplete/127.0.0.1:52120
channelInactive/127.0.0.1:52120
channelUnregistered/127.0.0.1:52120

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

N_A_S_A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值