使用LineBasedFrameDecoder编解码器,将数据进行处理。 这个是用换行为分隔符的。所以当没有换行的时候,那该咋办呢,可以看一下DelimiterBasedFrameDecoder。
TimeClient2.java
public class TimeClient2 {
private final String host = "127.0.0.1";
private final int port= 8099;
public static void main(String[] args) {
new TimeClient2().start();
}
private void start() {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new LineBasedFrameDecoder(1024));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new TimeClientHandler2());
}
});
ChannelFuture f = b.connect().sync();
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
group.shutdownGracefully().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
TimeClientHandler2.java
public class TimeClientHandler2 extends ChannelInboundHandlerAdapter{
private static final Logger logger = Logger.getLogger(TimeClientHandler2.class.getName());
private int counter;
private byte[] req;
public TimeClientHandler2() {
req = ("QUERY TIME ORDER"+System.getProperty("line.separator")).getBytes();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ByteBuf message = null;
for (int i = 0; i < 100; i++) {
message = Unpooled.buffer(req.length);
message.writeBytes(req);
ctx.writeAndFlush(message);
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String body = (String) msg;
System.out.println("Now is:"+body+";the counter is :"+ ++counter);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.warning("Unexpected exception from downStream:"+cause.getMessage());
ctx.close();
}
}
TimeServer2.java
/**
* 使用LineBasedFrameDecoder解决半包问题
* 工作原理:它依次遍历ByteBuf中的可读字节,判断是否有"\n"或者"\r\n",如果有,就以此位置为结束位置,从可读索引到结束位置区间的字节组成了一行。
* 支持配置单行的最大长度,如果连续读取超过最大长度仍没发现换行符,就抛出异常。
* StringDecoder将收到的对象转换成字符串
* @author author
*
*/
public class TimeServer2 {
private final int port =8099;
public static void main(String[] args) {
new TimeServer2().start();
}
private void start() {
EventLoopGroup group = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new LineBasedFrameDecoder(1024));//使用LineBasedFrameDecoder解决半包问题
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new TimeServerHandler2());
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
group.shutdownGracefully().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
TimeServerHandler2.java
public class TimeServerHandler2 extends ChannelInboundHandlerAdapter{
private int counter;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String body = (String)msg;//TimeServer2已经处理过的,所以可以强转
System.out.println("The time server receive order:"+body+";the counter is:"+ ++counter);
String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body)?new Date(System.currentTimeMillis()).toString():"BAD ORDER";
currentTime = currentTime +System.getProperty("line.separator");
ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
ctx.writeAndFlush(resp);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
DelimiterBasedFrameDecoder的处理案例,其实也没啥,就改一下编码器和分隔符,其他和上面的一样
EchoClient.java
public class EchoClient {
private final String host = "127.0.0.1";
private final int port= 8099;
public static void main(String[] args) {
new EchoClient().start();
}
private void start() {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture f = b.connect().sync();
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
group.shutdownGracefully().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
EchoClientHandler.java
public class EchoClientHandler extends ChannelInboundHandlerAdapter{
private int counter;
public static final String ECHO_REQ = "hi,caifen,welcome to guangzhou.$_";
public EchoClientHandler() {
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
for (int i = 0; i < 10; i++) {
ctx.writeAndFlush(Unpooled.copiedBuffer(ECHO_REQ.getBytes()));
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("This is "+ ++counter +"times receive server:["+msg+"]");
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
EchoServer.java
public class EchoServer {
private final int port =8099;
public static void main(String[] args) {
new EchoServer().start();
}
private void start() {
EventLoopGroup group = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(group)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new EchoServerHandler());
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
group.shutdownGracefully().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
EchoServerHandler.java
public class EchoServerHandler extends ChannelInboundHandlerAdapter{
private int counter = 0;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String body = (String) msg;
System.out.println("This is "+ ++counter +" times receive client:["+body+"]");
body +="love me.";
body +="$_";
ByteBuf echo = Unpooled.copiedBuffer(body.getBytes());
ctx.writeAndFlush(echo);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}