打印客户输出的数据并且向客户端回写数据
服务端代码
package com.guoyy.server;
import com.guoyy.handler.EchoServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
*
* @author guoyy
* 打印客户端输入的数据并回写数据给客户端
*/
public class EchoServer {
public static void main(String[] args) {
EchoServer es = new EchoServer();
try {
es.run(8080);
} catch (Exception e) {
e.printStackTrace();
}
}
public void run(int port) throws Exception{
// 主事件循环组(用来接收客户的连接)
EventLoopGroup bossGroup = new NioEventLoopGroup();
// 工作事件循环组(用来接收主事件循环组接收的连接并将连接注册到工作事件循环组)
EventLoopGroup workGroup = new NioEventLoopGroup();
// 帮助启动服务的类
ServerBootstrap server = new ServerBootstrap();
try {
// 设置主线程池和工作线程池
server.group(bossGroup, workGroup)
// 当接收到一个新的连接时实例化一个通道的时候创建的通道类型
.channel(NioServerSocketChannel.class)
// 当新接收的channel用于设置用户来配置该channel
.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
// EchoServerHandler是用来接收和输出数据的处理类
// 获取channel的通道链,并在最后添加EchoServerHandler
ch.pipeline().addLast(new EchoServerHandler());
}
})
// 设置等待连接数(主要是在三次握手中还没有被accept的连接数)
.option(ChannelOption.SO_BACKLOG, 128)
// 保持连接
.childOption(ChannelOption.SO_KEEPALIVE, true);
// 绑定端口和启动服务
ChannelFuture future = server.bind(port).sync();
System.out.println("server start on :" + port);
// 等待服务关闭(在服务端不会发生)
future.channel().closeFuture().sync();
} catch (Exception e) {
throw e;
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
package com.guoyy.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 EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
String receive = buf.toString(CharsetUtil.UTF_8);
System.out.println(receive);
// 将消息包裹成ByteBuf并通过ctx的writeAndFlush方法回写。也可以先调用write方法再调用flush方法
ctx.writeAndFlush(Unpooled.wrappedBuffer(("I have received your message[" + receive + "]").getBytes()));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
客户端使用telnet,效果为