很简单的一个例子,没有客户端,用 telnet 当客户端连接服务器
命令 telnet localhost 10086
任意输入后查看服务器响应
服务器端:
public class Server {
private int port;
public Server(int port) {
this.port = port;
}
public void startup() throws Exception {
// NioEventLoopGroup 是用来处理I/O操作的多线程事件循环器
// 实现服务端应用需要2个 NioEventLoopGroup
// 第一个经常被叫做‘boss’,用来接收进来的连接
// 第二个经常被叫做‘worker’,用来处理已经被接收的连接
// 一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// ServerBootstrap 是一个启动 NIO 服务的辅助启动类(配置参数等)
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup);
// 使用 NioServerSocketChannel 类创建 channel 实例
b.channel(NioServerSocketChannel.class);
// 这里的事件处理类 childHandler 经常会被用来处理一个最近的已经接收的 Channel
// ChannelInitializer 是一个特殊的处理类,他的目的是帮助使用者配置一个新的 Channel
// 如增加一些处理类比如 EchoChannelHandler 来配置一个新的 Channel
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
// ChannelPipeline 的执行顺序, 举例说明(官方文档)
// p.addLast("1", new InboundHandlerA());
// p.addLast("2", new InboundHandlerB());
// p.addLast("3", new OutboundHandlerA());
// p.addLast("4", new OutboundHandlerB());
// p.addLast("5", new InboundOutboundHandlerX());
// 如果是接收,执行顺序:1,2,5 (实现 ChannelInboundHandler 的处理类)
// 如果是流出,执行顺序:5,4,3 (实现 ChannelOutboundHandler 的处理类)
ch.pipeline().addLast(new ServerHandler());
}
});
// 配置 Channel 参数
// option() 是提供给NioServerSocketChannel 用来接收进来的连接。
// childOption() 是提供给由父管道 ServerChannel 接收到的连接,在这个例子中也是
// NioServerSocketChannel
b.option(ChannelOption.SO_BACKLOG, 128);
b.childOption(ChannelOption.SO_KEEPALIVE, true);
// 绑定端口,开始接收进来的连接
ChannelFuture f = b.bind(port).sync();
// 一直等待,直到socket被关闭,在这个例子中,这不会发生
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new Server(10086).startup();
}
}
自定义channelhandler类:
public class ServerHandler extends ChannelInboundHandlerAdapter {
// 事件处理方法。每当从客户端收到新的数据时,这个方法会在收到消息时被调用
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
System.out.print(in.toString(CharsetUtil.US_ASCII));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
// 当出现异常就关闭连接
ctx.close();
}
}
3038

被折叠的 条评论
为什么被折叠?



