导入相应的包
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.28.Final</version>
</dependency>
客户端
/**
* 客户端
*/
public class Client {
private String host;
private int port;
public Client(String host, int port) {
this.host = host;
this.port = port;
}
//启动客户端连接
public void start() {
//线程组
EventLoopGroup group = new NioEventLoopGroup();
try {
//客户端启动类
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)//加入线程组
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))//设置连接参数
.handler(new ClientHandler());//设置客户端连接的处理器
//阻塞直到连接完成
ChannelFuture connect = bootstrap.connect().sync();
//阻塞直到连接成功关闭
connect.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
group.shutdownGracefully().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Client client = new Client("127.0.0.1", 9999);
client.start();
}
}
客户端处理器
public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
//连接成功后,接收服务端响应的数据
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
System.out.println("接收到服务端响应的数据......" + byteBuf.toString(CharsetUtil.UTF_8));
}
//客户端连接成功后调用的
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端成功连接,并向服务端发送数据......");
ctx.writeAndFlush(Unpooled.copiedBuffer("Hello,Netty!", CharsetUtil.UTF_8));
}
//连接失败后调用
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("客户端连接失败");
cause.printStackTrace();
//关闭资源
ctx.close();
}
}
服务端
/**
* 服务端
*/
public class Server {
private int port;
public Server(int port) {
this.port = port;
}
public void start() {
EventLoopGroup group = new NioEventLoopGroup();
try {
ServerBootstrap sb = new ServerBootstrap();
//服务端共用一个Handler
final ServerHandler serverHandler = new ServerHandler();
sb.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>() {
/*接收到连接请求,新启一个socket通信,也就是channel,每个channel
* 有自己的事件的handler*/
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(serverHandler);
}
});
ChannelFuture sync = sb.bind().sync();
sync.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
group.shutdownGracefully().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Server(9999).start();
}
}
服务端处理器
/*指明我这个handler可以在多个channel之间共享,意味这个实现必须线程安全的。*/
@ChannelHandler.Sharable
public class ServerHandler extends ChannelInboundHandlerAdapter {
//服务端读取完客户端的所有数据后
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)/*flush掉所有的数据*/
.addListener(ChannelFutureListener.CLOSE);/*当flush完成后,关闭连接*/
}
//服务端读取客户端的数据
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf msg1 = (ByteBuf) msg;
System.out.println("服务端接收到客户端的数据......." + msg1.toString(CharsetUtil.UTF_8));
ctx.write(msg1);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
运行结果:
服务端:
客户端: