最近在学习netty练习下,先附上写的代码吧
注意不要使用5.0的版本了,官方直接废弃了,可以自己搜索下。因此只用4版本的。
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.50.Final</version> </dependency>
服务端的代码实现:
private static int port = 8080;
public static void main(String[] args) { _// boss__线程池负责接受请求 _ NioEventLoopGroup bossGroup = new NioEventLoopGroup(); _// work__线程池负责处理请求 _ NioEventLoopGroup workGroup = new NioEventLoopGroup(); // _创建__ServerBootstrap _ ServerBootstrap serverBootstrap = new ServerBootstrap(); _// NioServerSocketChannel__标记当前是服务器 _ serverBootstrap.group(bossGroup, workGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { // _处理每个请求__hanlder _ socketChannel.pipeline().addLast(new ServerHandler()); } }); // _绑定我们的端口号码 _ try { // _绑定端口号,同步等待成功 _ ChannelFuture future = serverBootstrap.bind(port).sync(); System.out.println("服务器启动成功:" + port); // _等待服务器监听端口 _ future.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { // _优雅的关闭连接 _ bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } }
ServerHandler类的实现
public class ServerHandler extends SimpleChannelInboundHandler { protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception { // 接受我们的数据 _ ByteBuf byteBuf = (ByteBuf) o; String request = byteBuf.toString(CharsetUtil.UTF_8); System.out.println("接受到的客户端消息:" + request); // 响应内容: _ channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer("这是服务端响应的消息", CharsetUtil.UTF_8)); } }
接下来开始写客户端的实现代码:
public static void main(String[] args) { _//__创建__nioEventLoopGroup _ NioEventLoopGroup group = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group).channel(NioSocketChannel.class).remoteAddress(new InetSocketAddress("127.0.0.1", 8080)).handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ClientHandler()); } }); try { // _发起同步连接 _ ChannelFuture sync = bootstrap.connect().sync(); sync.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { group.shutdownGracefully(); } }
ClientHandler类的实现
public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> { // _活跃通道可以发送消息 _ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { // _发送数据 _ ctx.writeAndFlush(Unpooled.copiedBuffer("活跃通道发生消息?", CharsetUtil.UTF_8)); } protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception { System.out.println("接收服务端响应的信息:" + byteBuf.toString(CharsetUtil.UTF_8)); } }
然后就可以运行起来看效果了。
粘包和拆包的问题可以通过利用编码器LineBaseDFrameDecoder解决。在服务端的和客户端分别添加如下代码。
// 设置我们分割最大长度为__1024 socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024)); // 获取数据的结果为__string__类型 socketChannel.pipeline().addLast(new StringEncoder());
同时发送的消息加上一个\n字符进行区分。