引言
最近在看《Netty实战》,其中一个案例是一个回显的客户端/服务端实现。这个以前在用原生jdk时是经典的案例。
但是唯一的区别在于以前是从控制台读取输入。
这个就是一个实现从控制台读取输入的案例。
服务端
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
public class Server {
private static final int port = 10086;
public static void main(String[] args) throws InterruptedException {
ServerBootstrap bootstrap = new ServerBootstrap();
NioEventLoopGroup group = new NioEventLoopGroup();
try {
bootstrap.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
String string = msg.toString(StandardCharsets.UTF_8);
System.out.println("server received: " + string);
ctx.write(msg);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("client: " + ctx.channel().remoteAddress() + " active!");
super.channelActive(ctx);
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("client: " + ctx.channel().remoteAddress() + " register!");
super.channelRegistered(ctx);
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("client: " + ctx.channel().remoteAddress() + " unregister!");
super.channelUnregistered(ctx);
}
});
}
});
ChannelFuture future = bootstrap.bind().sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully().sync();
}
}
}
客户端
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
public class Client {
private static String host = "127.0.0.1";
private static int port = 10086;
public static void main(String[] args) throws InterruptedException {
NioEventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
System.out.println("Client received: " + msg.toString(StandardCharsets.UTF_8));
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel active!");
ctx.writeAndFlush(Unpooled.copiedBuffer("hello server!", StandardCharsets.UTF_8));
}
});
}
});
ChannelFuture future = bootstrap.connect().sync();
Channel channel = future.channel();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line;
while (!"over".equals(line = bufferedReader.readLine())) {
System.out.println(line);
channel.writeAndFlush(Unpooled.copiedBuffer(line, StandardCharsets.UTF_9));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully().sync();
}
}
}
运行
首先启动server,然后启动client。
client先会输出:
channel active!
随后server输出:
client: /127.0.0.1:62414 register!
client: /127.0.0.1:62414 active!
server received: hello server!
然后切换到客户端的控制台:
可以查看服务端的输出: