TCP 粘包拆包基本介绍
接收端很难分辨出完整的数据包,因为 面向流的通信是无消息保护边界的
https://www.bilibili.com/video/BV1jK4y1s7GV?p=87
https://www.bilibili.com/video/BV1jK4y1s7GV?p=88
https://www.bilibili.com/video/BV1jK4y1s7GV?p=89
https://www.bilibili.com/video/BV1jK4y1s7GV?p=90
https://www.bilibili.com/video/BV1jK4y1s7GV?p=91
=
client
=====
package com.atguigu.tcp.client;
import com.atguigu.tcp.client.MyClientInitializer;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
/**
* Author: tz_wl
* Date: 2020/9/28 15:50
* Content:
*
* https://www.bilibili.com/video/BV1jK4y1s7GV?p=88
*/
public class MyClient {
public static void main(String[] args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new MyClientInitializer());
ChannelFuture channelFuture = bootstrap.connect("localhost", 8087).sync();
channelFuture.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
package com.atguigu.tcp.client;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
/**
* Author: tz_wl
* Date: 2020/9/28 19:38
* Content:
*/
public class MyClientInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
ChannelPipeline pipeline = sc.pipeline();
pipeline.addLast(new MyClientHandler());
}
}
package com.atguigu.tcp.client;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
/**
* Author: tz_wl
* Date: 2020/9/28 19:39
* Content:
*/
public class MyClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
private int count;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//使用客户端发送10 条数据 hello,server
for (int i=0;i<100;++i){
ByteBuf byteBuf = Unpooled.copiedBuffer("hello,server" + i, CharsetUtil.UTF_8);
ctx.writeAndFlush(byteBuf);
}
}
//接收从服务器发送的数据
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
byte[] bytes = new byte[msg.readableBytes()];
msg.readBytes(bytes);
String message = new String(bytes,CharsetUtil.UTF_8);
System.out.println("客户端接收到消息==="+message);
System.out.println("客户端接收到消息的数量===="+(++this.count));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
=
server
======
package com.atguigu.tcp.server;
import com.atguigu.tcp.server.MyServerInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
* Author: tz_wl
* Date: 2020/9/28 14:30
* Content:
*
* https://www.bilibili.com/video/BV1jK4y1s7GV?p=88
*/
public class MyServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new MyServerInitializer());
ChannelFuture future = serverBootstrap.bind(8087).sync();
future.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
package com.atguigu.tcp.server;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
/**
* Author: tz_wl
* Date: 2020/9/28 19:42
* Content:
*/
public class MyServerInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel sc) throws Exception {
ChannelPipeline pipeline = sc.pipeline();
pipeline.addLast(new MyServerHandler());
}
}
package com.atguigu.tcp.server;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
import java.util.UUID;
/**
* Author: tz_wl
* Date: 2020/9/28 19:43
* Content:
*/
public class MyServerHandler extends SimpleChannelInboundHandler<ByteBuf> {
private int count;
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
byte[] bytes=new byte[msg.readableBytes()];
msg.readBytes(bytes);
//将buffer转换成字符串
String s = new String(bytes, CharsetUtil.UTF_8);
System.out.println("服务端接收到 客户端 "+ ctx.channel().remoteAddress()+"发来的数据: "+s);
System.out.println("服务器端接收到消息量"+ (++this.count));
//服务器回送数据给客户端,看客户端如何接收
ByteBuf responseBody = Unpooled.copiedBuffer(UUID.randomUUID().toString(), CharsetUtil.UTF_8);
ctx.writeAndFlush(responseBody);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}