最近在学习netty练习下,先附上写的代码吧
注意不要使用5.0的版本了,官方直接废弃了,可以自己搜索下。因此只用4版本的。
<!-- https://mvnrepository.com/artifact/io.netty/netty-all --> <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字符进行区分。
来源:oschina
链接:https://my.oschina.net/uwith/blog/4291865