1、客户端代码及关键类说明:
/**
* netty5的客户端
* @author -zhengzx-
*
*/
public class ClientSocket {
public static void main(String[] args) {
//服务类
Bootstrap bootstrap = new Bootstrap();
//worker
EventLoopGroup worker = new NioEventLoopGroup();
try {
//设置线程池
bootstrap.group(worker);
//设置socket工厂、
bootstrap.channel(NioSocketChannel.class);
//设置管道
bootstrap.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ClientSocketHandler());
}
});
ChannelFuture connect = bootstrap.connect("127.0.0.1", 10101);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while(true){
System.out.println("请输入:");
String msg = bufferedReader.readLine();
connect.channel().writeAndFlush(msg);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
worker.shutdownGracefully();
}
}
}
- EventLoopGroup:客服端需要指定EvnetLoopGroup,Netty5中实例为NioEventLoopGroup:表示一个NIO的EvnetLoopGroup。
- ChannelType:指定Channel的类型,客户端为NioSocketChannel。在 Netty 中, Channel 是一个 Socket 的抽象, 它为用户提供了关于 Socket 状态(是否是连接还是断开) 以及对 Socket 的读写等操作. 每当 Netty 建立了一个连接后, 都会有一个对应的 Channel 实例。
- Handler:设置数据的处理类。
public class ClientSocketHandler extends SimpleChannelInboundHandler<String>{
@Override
protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("客户端接受消息:"+msg);
}
}
- ChannelPipeline:在实例化一个 Channel 时, 必然伴随着实例化一个 ChannelPipeline。
2、服务端代码及说明
/**
* Netty5服务端
* @author zhengzx
*
*/
public class ServerSocket {
public static void main(String[] args) {
//创建服务类
ServerBootstrap serverBootstrap = new ServerBootstrap();
//boss和worker
NioEventLoopGroup boss = new NioEventLoopGroup();
NioEventLoopGroup worker = new NioEventLoopGroup();
try {
//设置线程池
serverBootstrap.group(boss,worker);
//设置socket工厂,Channel 是对 Java 底层 Socket 连接的抽象
serverBootstrap.channel(NioServerSocketChannel.class);
//设置管道工厂
serverBootstrap.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
//设置后台转换器(二进制转换字符串)
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ServerSocketHandler());
}
});
//设置TCP参数
serverBootstrap.option(ChannelOption.SO_BACKLOG, 2048);//连接缓冲池大小
serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);//维持连接的活跃,清除死连接
serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true);//关闭超时连接
ChannelFuture future = serverBootstrap.bind(10010);//绑定端口
System.out.println("服务端启动");
//等待服务端关闭
future.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放资源
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
- ventLoopGroup: 不论是服务器端还是客户端, 都必须指定 EventLoopGroup. 在这个例子中, 指定了 NioEventLoopGroup, 表示一个 NIO 的EventLoopGroup, 不过服务器端需要指定两个 EventLoopGroup, 一个是 bossGroup, 用于处理客户端的连接请求; 另一个是 workerGroup, 用于处理与各个客户端连接的 IO 操作。
- ChannelType: 指定 Channel 的类型. 因为是服务器端, 因此使用了 NioServerSocketChannel。
- Handler: 设置数据的处理器。
public class ServerSocketHandler extends SimpleChannelInboundHandler<String>{
@Override
protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println(msg);
//返回字符串
ctx.writeAndFlush("hi");
}
}