您的位置:首页 > 其它

Netty学习之服务端客户端搭建(1)

2017-12-27 02:42 477 查看

0.Netty简介

    Netty是最流行的NIO框架,它的健壮性、功能、性能、可定制性和可扩展性在同类框架都是首屈一指的。它已经得到成百上千的商业/商用项目验证,如Hadoop的RPC框架Avro、RocketMQ以及主流的分布式通信框架Dubbox等等。

1.服务端

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

public class NettyServer {

public static void main(String[] args) {
// TODO Auto-generated method stub
EventLoopGroup parentGroup=new NioEventLoopGroup();//设置boss线程
EventLoopGroup childGroup=new NioEventLoopGroup();//  设置worker线程

try {
ServerBootstrap serverBootstrap=new ServerBootstrap();//设置服务类
serverBootstrap.group(parentGroup, childGroup); //设置线程池
serverBootstrap.channel(NioServerSocketChannel.class); //设置socket工厂
//设置参数,TCP参数
serverBootstrap.option(ChannelOption.SO_BACKLOG, 2048)//serverSocketchannel的设置,链接缓冲池的大小
.childOption(ChannelOption.SO_KEEPALIVE, true)//socketchannel的设置,维持链接的活跃,清除死链接
.childOption(ChannelOption.TCP_NODELAY, true)//socketchannel的设置,关闭延迟发送
.childHandler(new ChannelInitializer<SocketChannel >() {

@Override
protected void initChannel(SocketChannel ch) throws Exception {
// TODO Auto-generated method stub
//	ch.pipeline().addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()[0]));

ch.pipeline().addLast(new StringDecoder()); //解码器
ch.pipeline().addLast(new StringEncoder()); //编码器
ch.pipeline().addLast(new SimpleHandler());  //自定义处理器
}

});

ChannelFuture future=	serverBootstrap.bind(8080).sync();  //绑定端口
future.channel().closeFuture().sync();     //等待服务端关闭
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
//释放资源
parentGroup.shutdownGracefully();
childGroup.shutdownGracefully();
}

}

}
接着是自定义处理器类
import java.nio.charset.Charset;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class SimpleHandler extends ChannelInboundHandlerAdapter {

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// TODO Auto-generated method stub
System.out.println("服务端开始读取数据======");
System.out.println((String)msg);
ctx.channel().writeAndFlush("hello,client");   //回写数据给客户端
}

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
// TODO Auto-generated method stub
super.userEventTriggered(ctx, evt);
}
}

2.客户端

import java.nio.charset.Charset;
import java.util.Scanner;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
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.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.AttributeKey;

public class NettyClient {
//静态化客户端初始设置
public static EventLoopGroup group=null;
public static Bootstrap bootstrap=null;
static {
group=new NioEventLoopGroup();    //设置worker线程
bootstrap=new Bootstrap();        //设置服务类
bootstrap.channel(NioSocketChannel.class); //设置工厂
bootstrap.group(group);           //设置线程池
bootstrap.option(ChannelOption.SO_KEEPALIVE, true)   //设置管道
.handler(new ChannelInitializer<Channel>() {

@Override
protected void initChannel(Channel ch) throws Exception {
// TODO Auto-generated method stub
//	ch.pipeline().addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()[0]));
ch.pipeline().addLast(new StringDecoder());  //译码器
ch.pipeline().addLast(new StringEncoder());  //编码器
ch.pipeline().addLast(new ClientHandler());  //自定义处理器
}
});
}
public static void main(String[] args) {
// TODO Auto-generated method stub

EventLoopGroup group=new NioEventLoopGroup();
try {
ChannelFuture future=bootstrap.connect("localhost",8080).sync(); //获取连接
Scanner in=new Scanner(System.in);
System.out.println("请输入内容给服务端:");
while(in.hasNext()) {              //输入
String person=in.nextLine();
future.channel().writeAndFlush(person);   //写进通道
}

/*ByteBuf buf=PooledByteBufAllocator.DEFAULT.buffer();
buf.writeBytes(person.getBytes(Charset.defaultCharset()));
future.channel().writeAndFlush(buf);*/
//future.channel().writeAndFlush(person);
//future.channel().writeAndFlush(Delimiters.lineDelimiter()[0]);

//	future.channel().closeFuture().sync();
//	Object result=future.channel().attr(AttributeKey.valueOf("ChannelKey")).get();
//	System.out.println("haha========"+result);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
group.shutdownGracefully();  //释放资源
}

}

}


接着是客户端自定义类

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.AttributeKey;

public class ClientHandler extends ChannelInboundHandlerAdapter {

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// TODO Auto-generated method stub
System.out.println("客户端开始读取数据");
System.out.println("接收到服务器数据为:"+msg.toString());
//	ctx.channel().attr(AttributeKey.valueOf("ChannelKey")).set(msg.toString());
//	ctx.channel().close();
}
}

3.运行结果



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: