Netty实战

Netty实战,小傅哥博客Netty实战的实现

代码地址

案例一 TCP服务端

要求1: 在客户端连接后打印客户端端的ip和端口号

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;

public class DemoNetty101 {
    public static void main(String[] args) {
        DemoNetty101 demoNetty101 = new DemoNetty101();
        demoNetty101.startTCP();
    }

    private void startTCP() {
        // 一个监听工作组,在很多写法中叫做master组
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        // 一个工作监听组,在很多写法中交child组
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap server = new ServerBootstrap();
            server.group(bossGroup, workerGroup)
                    // 设置非阻塞模式
                    .channel(NioServerSocketChannel.class) 
                    // 添加自定义处理器
                    .childHandler(new TCPServerInitializer());
            ChannelFuture f = server.bind(8088).sync();
            System.out.println("Http Server started, Listening on " + 8088);
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }
}
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;

public class TCPServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        System.out.println("初始化连接成功");
        System.out.println(socketChannel.remoteAddress().getHostString()+":"+socketChannel.remoteAddress().getPort());
    }
}

案例二 TCP服务端

要求1: 在客户端连接后打印客户端端的ip和端口号 要求2:能打印出客户端发送的内容

案例三 TCP服务端

要求1: 在客户端连接后打印客户端端的ip和端口号 要求2: 使用内置的协议解析器解码客户端发送的内容 要求3:使用字符串解码器解码, 打印出客户端发送的内容

案例四 TCP服务端

要求1: 让入站数据经过多个Handle处理器 要求2: 每个处理器都知道客户端关闭了连接

案例五 TCP服务端

要求1: 能将收到的内容原样回复给客户端程序(这里的变化主要是要将返回的数据进行编码)

案例六 TCP服务端

要求1: 使用内置的字符串编解码器

案例七 TCP服务端

要求1: 接收多个客户端链接(其实就是可以缓存多个客户端链接),并每次响应给所有客户端(群发消息)

案例八 TCP客户端

要求1: 新建客户端能正常连接到一个服务端

案例九 TCP客户端

要求1: 新建客户端能正常连接到一个服务端 要求2: 使用netty自带的换行解析器拆分数据, 并使用字符串解码编码器来打印服务端信息和返回服务端字符串

案例十 TCP客户端和服务端

要求1: 使用继承ChannelInboundHandlerAdapter处理入站信息 使用继承ChannelOutboundHandlerAdapter处理出站时间

@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
        System.out.println("链接报告开始");
        System.out.println("链接报告信息:本客户端链接到服务端。channelId:" + socketChannel.id());
        System.out.println("链接报告完毕");
        socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024))

        .addLast(new StringDecoder(Charset.forName("GBK")))
        .addLast(new StringEncoder(Charset.forName("GBK")))

        .addLast(new Outbound1())
        .addLast(new Outbound2())

        .addLast(new Inbound1())
        //必须使用ctx.writeAndFlush(message); 否则出站处理器收不到消息,
        //如果定义到Outbound前面相当于数据提前掉头了
        .addLast(new Inbound2())
        ;
        }
//在Inbound2中必须使用ctx.writeAndFlush(message); 也就是最后一个入站处理器必须使用ctx.writeAndFlush(message); 否则出站处理器收不到消息
// 同时如果在Inbound1中使用了ctx.writeAndFlush(message); 那么数据将不再向Inbound2中传递
//根据处理器执行顺序,数据会先走Outbound2 再走Outbound1, 所以再Outbund1中必须调用ctx.writeAndFlush(message, promise);

案例十一 UDP客户端和服务端

案例十二 简单的http服务器