服务端启动流程
package com.example.netty;
import com.example.netty.handler.HelloServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class HelloServer {
public static void main(String[] args) {
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
//1. 指定线程组
serverBootstrap.group(bossGroup, workerGroup)
.localAddress(8000)//2. 指定端口
.channel(NioServerSocketChannel.class)//3. 指定IO模型
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new HelloServerHandler());
}
});//4. 配置业务处理逻辑类
//5. 绑定端口
serverBootstrap.bind().addListener((future)->{
if(future.isSuccess()){
System.out.println("端口绑定成功");
}else{
System.out.println("端口绑定失败:"+future.cause());
}
});
}
}
bossGroup
和workerGroup
可以看作是传统IO网络编程的两个线程组,bossGroup
负责 accept 新的socket连接,workerGroup
负责socket连接的读写。ServerBootstrap
是服务端引导类,负责.group(bossGroup, workerGroup)
配置线程模型;.channel
指定IO模型,NioServerSocketChannel.class
是NIO模型,OioServerSocketChannel.class
是传统IO模型;.childHandler
配置业务逻辑处理。.bind()
绑定端口,该方法是异步执行,所以需要配置监听器。
服务端业务处理类
package com.example.netty.handler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
public class HelloServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf = (ByteBuf) msg;
System.out.println(byteBuf.toString(CharsetUtil.UTF_8));
ctx.writeAndFlush(Unpooled.copiedBuffer("hello client".getBytes()));
}
}
主要打印客户端发送的消息并返回Hello Client。
客户端启动流程
package com.example.netty;
import com.example.netty.handler.HelloClientHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
public class HelloClient {
public static void main(String[] args) {
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
//1. 配置线程组
bootstrap.group(workerGroup)
.channel(NioSocketChannel.class)//2. 指定IO模型
.remoteAddress("127.0.0.1", 8000)//3. 指定连接ip和端口
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new HelloClientHandler());
}
});//4. 配置业务处理逻辑
//5. 连接
bootstrap.connect().addListener(future -> {
if(future.isSuccess()){
System.out.println("连接成功");
}else{
System.out.println("连接失败:" + future.cause());
}
});
}
}
客户端引导类为Bootstrap
,而服务端为ServerBootstrap
业务处理逻辑类
package com.example.netty.handler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
public class HelloClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer("hello server".getBytes()));
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf = (ByteBuf) msg;
System.out.println("recieve from server:" + byteBuf.toString(CharsetUtil.UTF_8));
}
}
主要在连接后向服务端发送Hello Server,并接受打印服务端返回消息。