服务端:
public class NettySer {
public static void main(String[] args) {
NettySer ns = new NettySer();
ns.start();
}
private void start() {
NioEventLoopGroup boss = new NioEventLoopGroup(1);
NioEventLoopGroup worker = new NioEventLoopGroup();// 默认为cpu数乘2
try {
ServerBootstrap sb = new ServerBootstrap();
// 设置服务端ServerBootStrap启动参数
sb.group(boss, worker);
sb.channel(NioServerSocketChannel.class); // 我要指定使用NioServerSocketChannel这种类型的通道
sb.option(ChannelOption.SO_BACKLOG, 1024)// 设置tcp缓冲区, 支持多少个客户端连接
.option(ChannelOption.SO_SNDBUF, 1024)// 设置发送缓冲大小
.option(ChannelOption.SO_RCVBUF, 1024);// 设置接收缓冲大小
sb.childHandler(new ChannelInitializer<Channel>() {// 一定要使用 childHandler 去绑定具体的事件处理器
@Override
protected void initChannel(Channel ch) throws Exception {
// ch.pipeline().addLast(new FixedLengthFrameDecoder(10));
// ch.pipeline().addLast(new StringEncoder());
// ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new MyMessageEncoder());
ch.pipeline().addLast(new MyMessageDecoder());
ch.pipeline().addLast(new SimpleChannelInboundHandler<MyRpcMessage>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, MyRpcMessage msg) throws Exception {
System.out.println("[ header = " + msg.header + ", content = " + msg.content + " ]");
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("client active");
super.channelActive(ctx);
}
});
// ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
//
// @Override
// protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
// InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();
// String clientIp = ipSocket.getAddress().getHostAddress();
// System.out.println(clientIp + " 说: " + msg);
// ctx.channel().writeAndFlush(Unpooled.wrappedBuffer("i am fine".getBytes()));
// }
//
// @Override
// public void channelActive(ChannelHandlerContext ctx) throws Exception {
// InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();
// String clientIp = ipSocket.getAddress().getHostAddress();
// System.out.println(clientIp + " client active!");
// super.channelActive(ctx);
// }
//
// });
}
});
// 绑定指定的端口进行监听
ChannelFuture f = sb.bind(9090).sync();
// 等待服务端监听端口关闭
System.out.println("绑定前, 输出。。。。。。。。");
f.channel().closeFuture().sync();
System.out.println("绑定后, 输出。。。。。。。。");//没输出 说明卡在上面一行
} catch (Exception e) {
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
客户端:
public class NettyCli {
public static void main(String[] args) {
NioEventLoopGroup worker = new NioEventLoopGroup();// 默认为cpu数乘2
try {
Bootstrap b = new Bootstrap();
b.group(worker);
b.channel(NioSocketChannel.class);
b.handler(new ChannelInitializer() {
@Override
protected void initChannel(Channel ch) throws Exception {
// ch.pipeline().addLast(new FixedLengthFrameDecoder(10));
// ch.pipeline().addLast(new StringEncoder());
// ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new MyMessageEncoder());
ch.pipeline().addLast(new MyMessageDecoder());
ch.pipeline().addLast(new SimpleChannelInboundHandler<MyRpcMessage>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, MyRpcMessage msg) throws Exception {
System.out.println("[ header = " + msg.header + ", content = " + msg.content + " ]");
}
});
// ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
//
// @Override
// protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
// System.out.println("server say:" + msg);
// }
// });
}
});
// 连接Server
ChannelFuture future = b.connect("127.0.0.1", 9090).sync();
// 发送消息给Server
MyRpcMessage msg = new MyRpcMessage(5, "这里是自定义协议的正文部分");
// future.channel().writeAndFlush(Unpooled.wrappedBuffer("hello abcdefghijk".getBytes()));
future.channel().writeAndFlush(msg);
// 等待连接关闭
future.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
worker.shutdownGracefully();
}
}
}
自定义协议:
public class MyRpcMessage {
int header; //协议头
String content;//协议正文
public MyRpcMessage(int header, String content) {
this.header = header;
this.content = content;
}
}
协议编码器:
public class MyMessageEncoder extends MessageToByteEncoder<MyRpcMessage>{
@Override
protected void encode(ChannelHandlerContext arg0, MyRpcMessage msg, ByteBuf out) throws Exception {
out.writeInt(msg.header);
out.writeBytes(msg.content.getBytes());
}
}
协议解码器:
public class MyMessageDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext arg0, ByteBuf in, List<Object> arg2) throws Exception {
int header = in.readInt();// 读协议头
byte[] data = new byte[in.readableBytes()];
in.readBytes(data);// 读协议正文
String content = new String(data);
MyRpcMessage msg = new MyRpcMessage(header, content);
arg2.add(msg);
}
}