欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Netty初识之DiscardServer

程序员文章站 2024-03-09 14:28:23
...

Netty

Netty项目是为了快速开发可维护的高性能高可扩展性协议服务器和客户端而努力提供异步事件驱动的网络应用程序框架和工具。换句话说,Netty是一个NIO客户端服务器框架,可以快速轻松地开发诸如协议服务器和客户端之类的网络应用程序。它大大简化了网络编程流程,如TCP和UDP套接字服务器开发。

Tomcat和Netty的比较

Netty和Tomcat最大的区别就在于通信协议,Tomcat是基于Http协议的,他的实质是一个基于http协议的web容器,但是Netty不一样,他能通过编程自定义各种协议,因为netty能够通过codec自己来编码/解码字节流,完成类似redis访问的功能,这就是netty和tomcat最大的不同

 

Netty特点:

  1. 并发高
  2. 传输快
  3. 封装好

 

Netty初识之DiscardServer

 

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.sengen</groupId>
  <artifactId>nettydemos</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>nettydemos</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.netty</groupId>
      <artifactId>netty-all</artifactId>
      <version>4.0.32.Final</version>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
package com.sengen.netty_beginner;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
 * Created by Administrator on 2018/8/17.
 * 描述:DiscardServer 启动类
 * @author Young
 * @create 2018-08-17 14:35
 */
public class DiscardServer {
    private int port;

    public DiscardServer(int port) {
        this.port = port;
    }

    public static void main(String[] args) {
        int port;
        if(args.length>0){
            port = Integer.valueOf(args[1]);
        }else {
            port = 8080;
        }
        System.out.println("准备启动中.........");
        new DiscardServer(port).run();
        //好像永远都执行不到回家的代码......
        System.out.println("跑完了....肥噶!");
    }

    private void run() {
        /**NioEventLoopGroup是一个处理I/O操作的多线程事件循环.Netty为不同类型的传输提供了各种EventLoopGroup实现.在这个例子中,我们正在实现一个
         * 服务器端应用程序,因此将使用两个NioEventLoopGroup.
         * 第一个 通常称为老板,接收传入的连接;
         * 第二个 通常称为工人,一旦老板接收连接并将接受的连接注册给工作人员,就处理接收的连接的流量.
         *        使用多少线程以及他们如何映射到创建的通道取决于EventLoopGroup实现,甚至可以通过构造函数进行配置.
         */
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try{
            /**
             * ServerBootstrap是一个帮助类,用于设置服务器.可以直接使用Channel设置服务器.但是一般情况都不这样做..
             **/
            ServerBootstrap sb = new ServerBootstrap();
            sb.group(bossGroup,workerGroup)
                    /**
                     * 在这里,我们指定使用NioServerSocketChannel类来实例化一个新的Channel来接收传入的连接.
                     * (每个客户端连接服务端,我们都为他们创建一个channel,那么这个channel对于面向对象的我们来说就是一个类,我们统一对于我们接收
                     * 到的连接都初始化为:NioServerSocketChannel)
                     */
                    .channel(NioServerSocketChannel.class)
                    /**
                     * 这里指定的处理程序将始终由新接收的Channel进行评估.ChannelInitializer是一个特殊的处理程序,旨在帮助用户配置新的Channel.
                     * 若想通过添加一些处理程序(如DiscardServerHandler)来配置新Channel的ChannelPipeline来实现网络应用程序.
                     * 随着应用程序的复杂化,可能在管道中添加更多的处理程序..(其实这就是需要自己重新实现包含自己处理逻辑的Channel.
                     * 类似于DiscardServerHandler,继承ChannelInboundHandlerAdapter一样)
                     * */
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline().addLast(new DiscardServerHandler());
                        }
                    })
                    /**
                     * 设置特定于Channel实现的参数.正在编写一个TCP/IP服务器.因此可以设置套接字选项.如tcpNoDelay和keepAlive
                     *
                     * option()和childOption()方法.
                     * option()用于接收传入连接的NioServerChannel.
                     * childOption()用于在这种情况下由父级ServerChannel接收的通道,即NioServerSocketChannel.
                     * 个人认为:前者用于配置父级Channel,后者配置自定义的子集Channel.
                    */
                    .option(ChannelOption.SO_BACKLOG,128)
                    .childOption(ChannelOption.SO_KEEPALIVE,true);

            ChannelFuture future = sb.bind(port).sync();
            future.channel().closeFuture().sync();

        }catch(Exception e){
            System.out.println("有异常,快跑...........");
        }finally{
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }


}
package com.sengen.netty_beginner;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

import java.net.SocketAddress;

/**
 * Created by Administrator on 2018/8/17.
 * 描述:手动完成比hello world还简单的程序
 * @author Young
 * @create 2018-08-17 14:29
 */
public class DiscardServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //将Object强转成ByteBuf(引用计数对象)
//        ((ByteBuf)msg).release();
        ByteBuf in = (ByteBuf) msg;
        try {
            while (in.isReadable()) {
                Channel channel = ctx.channel();
                SocketAddress socketAddress = channel.remoteAddress();
                System.out.println(socketAddress+"连接了你");
                System.out.print((char) in.readByte());
                System.out.flush();
            }
        } finally {
            ReferenceCountUtil.release(msg);
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        cause.printStackTrace();
        System.out.println(ctx.channel().remoteAddress()+"强迫关闭了连接");
        System.out.println("跑完了......肥噶!");
        ctx.close();
    }
}

控制台启动main方法...网页和cmd都可以访问.....localhost:8080.....localhost改成ip通用的...

 

我感觉我要把我的github用起来了...贴代码不方便了.

 

相关标签: netty