NIO高级编程与Netty入门概述

NIO高级编程与Netty packagecom.itmayiedu; importjava.net.InetSocketAddress; importjava.util.Scanner; importjava.util.concurrent.ExecutorService; importjava.util.concurrent.Executors; ... 阅读详情

1. NIO同步阻塞与同步非阻塞

1.1 BIO与NIO

IO(BIO)和NIO区别:其本质就是阻塞和非阻塞的区别
阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,就会一直等待,直到传输完毕为止。

非阻塞概念:应用程序直接可以获取已经准备就绪好的数据,无需等待。
IO为同步阻塞形式,NIO为同步非阻塞形式,NIO并没有实现异步,在JDK1.7后升级NIO库包,支持异步非阻塞

BIO:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

NIO:同步非阻塞式IO,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

AIO(其实就是升级的NIO2.0,仅jdk7以上支持):异步非阻塞式IO,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

同步时,应用程序会直接参与IO读写操作,并且我们的应用程序会直接阻塞到某一个方法上,直到数据准备就绪,或者采用轮训的策略实时检查数据的就绪状态,如果就绪则获取数据.

异步时,则所有的IO读写操作交给操作系统,与我们的应用程序没有直接关系,我们程序不需要关系IO读写,当操作系统完成了IO读写操作时,会给我们应用程序发送通知,我们的应用程序直接拿走数据极即可。

注:阻塞IO只与网络相关,本地没有阻塞IO概念。

1.2 伪异步

由于BIO一个客户端需要一个线程去处理,因此我们进行优化,后端使用线程池来处理多个客户端的请求接入,形成客户端个数M:线程池最大的线程数N的比例关系,其中M可以远远大于N,通过线程池可以灵活的调配线程资源,设置线程的最大值,防止由于海量并发接入导致线程耗尽。
原理:
当有新的客户端接入时,将客户端的Socket封装成一个Task(该Task任务实现了java的Runnable接口)投递到后端的线程池中进行处理,由于线程池可以设置消息队列的大小以及线程池的最大值,因此,它的资源占用是可控的,无论多少个客户端的并发访问,都不会导致资源的耗尽或宕机。

在下面1.3中的代码实际上都是伪异步,服务端接受请求过程中仍须等待。

1.3 使用多线程支持多个请求

服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善


/**
 * @Auther: 洺润Star
 * @Date: 2020/3/8 14:52
 * @Description:使用多线程改善tcp服务器&伪异步
 */
class TcpServerThread {
    public static void main(String[] args) throws IOException {
        System.out.println("tcp协议:服务端启动");
        ServerSocket serverSocket = new ServerSocket(8080);

        try {
            while (true){
                //通过多线程解决的仅仅是处理数据,但在此处仍需要等待
                Socket accept = serverSocket.accept();
                new Thread(() -> {
                    try {
                        InputStream inputStream = accept.getInputStream();
                        byte[] bytes = new byte[1024];
                        int read = inputStream.read(bytes);
                        String str = new String(bytes,0,read);
                        System.out.println("接收到的内容:"+str);
                        Thread.sleep(5000);
                        System.out.println("内容处理线程执行完毕,约耗时5秒");
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }).start();
                System.out.println("服务端本次等待结束,准备监听下次请求");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            serverSocket.close();
        }

    }
}
public class TcpClientThread {
    public static void main(String[] args) throws IOException {
        System.out.println("tcp协议:客户端启动");
        Socket socket = new Socket("127.0.0.1",8080);
        OutputStream outputStream = socket.getOutputStream();
        byte[] bytes = "我是洺润Star".getBytes();
        outputStream.write(bytes);
        socket.close();
    }
}

1.4 使用线程池管理线程

/**
 * @Auther: 洺润Star
 * @Date: 2020/3/8 14:53
 * @Description:使用线程池改善tcp服务端
 */
class TcpServerThreadPool {
    public static void main(String[] args) throws IOException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        System.out.println("tcp协议:服务端启动");
        ServerSocket serverSocket = new ServerSocket(8080);
        try {
            while (true){
                Socket accept = serverSocket.accept();
                executorService.execute(() -> {
                    try {
                        InputStream inputStream = accept.getInputStream();
                        byte[] bytes = new byte[1024];
                        int read = inputStream.read(bytes);
                        String s = new String(bytes, 0, read);
                        System.out.println("接收到的内容:"+s);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            serverSocket.close();
        }

    }
}
public class TcpClientThreadPool {
    public static void main(String[] args) throws IOException {
        System.out.println("tcp协议:客户端启动");
        Socket socket = new Socket("127.0.0.1",8080);
        OutputStream outputStream = socket.getOutputStream();
        byte[] bytes = "我是洺润Star".getBytes();
        outputStream.write(bytes);
        socket.close();
    }
}

1.5 IO模型关系

同步阻塞I/O(BIO)伪异步I/O同步非阻塞I/O(NIO)异步非阻塞I/O(AIO)
客户端个数:I/O线程1:1M:N(其中M可以大于N)M:1(一个IO线程处理多个客户端连接)M:0(不需要启动额外的IO线程,被动回调)
I/O类型(阻塞)阻塞IO阻塞IO非阻塞IO非阻塞IO

1.6 什么是阻塞

阻塞概念:应用程序在获取网络数据的时候,如果网络传输很慢,那么程序就一直等着,直接到传输完毕。

1.7 什么是非阻塞

应用程序直接可以获取已经准备好的数据,无需等待.
IO为同步阻塞形式,NIO为同步非阻塞形式。NIO没有实现异步,在JDK1.7之后,升级了NIO库包,支持异步非阻塞通讯模型NIO2.0(AIO)

1.8 NIO非阻塞代码

//nio   异步非阻塞
class Client {

	public static void main(String[] args) throws IOException {
		System.out.println("客户端已经启动....");
		// 1.创建通道
		SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8080));
		// 2.切换异步非阻塞
		sChannel.configureBlocking(false);
		// 3.指定缓冲区大小
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		Scanner scanner=  new Scanner(System.in);
		while (scanner.hasNext()) {
			String str=scanner.next();
			byteBuffer.put((new Date().toString()+"\n"+str).getBytes());
			// 4.切换读取模式
			byteBuffer.flip();
			sChannel.write(byteBuffer);
			byteBuffer.clear();
		}
		sChannel.close();
	}

}

// nio
class Server {
	public static void main(String[] args) throws IOException {
		System.out.println("服务器端已经启动....");
		// 1.创建通道
		ServerSocketChannel sChannel = ServerSocketChannel.open();
		// 2.切换读取模式
		sChannel.configureBlocking(false);
		// 3.绑定连接
		sChannel.bind(new InetSocketAddress(8080));
		// 4.获取选择器
		Selector selector = Selector.open();
		// 5.将通道注册到选择器 "并且指定监听接受事件"
		sChannel.register(selector, SelectionKey.OP_ACCEPT);
		// 6. 轮训式 获取选择 "已经准备就绪"的事件
		while (selector.select() > 0) {
			// 7.获取当前选择器所有注册的"选择键(已经就绪的监听事件)"
			Iterator<SelectionKey> it = selector.selectedKeys().iterator();
			while (it.hasNext()) {
				// 8.获取准备就绪的事件
				SelectionKey sk = it.next();
				// 9.判断具体是什么事件准备就绪
				if (sk.isAcceptable()) {
					// 10.若"接受就绪",获取客户端连接
					SocketChannel socketChannel = sChannel.accept();
					// 11.设置阻塞模式
					socketChannel.configureBlocking(false);
					// 12.将该通道注册到服务器上
					socketChannel.register(selector, SelectionKey.OP_READ);
				} else if (sk.isReadable()) {
					// 13.获取当前选择器"就绪" 状态的通道
					SocketChannel socketChannel = (SocketChannel) sk.channel();
					// 14.读取数据
					ByteBuffer buf = ByteBuffer.allocate(1024);
					int len = 0;
					while ((len = socketChannel.read(buf)) > 0) {
						buf.flip();
						System.out.println(new String(buf.array(), 0, len));
						buf.clear();
					}
				}
				it.remove();
			}
		}

	}
}

1.9 选择KEY

在SelectionKey类的源码中我们可以看到如下的4中属性,四个变量用来表示四种不同类型的事件:可连接、可接受连接、可读、可写

  1. SelectionKey.OP_CONNECT
  2. SelectionKey.OP_ACCEPT
  3. SelectionKey.OP_READ
  4. SelectionKey.OP_WRITE

如果要使用多个事件,那么可以用“位或”操作符将常量连接起来,如下:

int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;

2. Netty快速入门

2.1 什么是Netty

Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。

2.2 Netty应用场景

  1. 分布式开源框架中dubbo、Zookeeper,RocketMQ底层rpc通讯使用就是netty。
  2. 游戏开发中,底层使用netty通讯。

2.3 为什么选择netty

在本小节,我们总结下为什么不建议开发者直接使用JDK的NIO类库进行开发的原因:

  1. NIO的类库和API繁杂,使用麻烦,你需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等;
  2. 需要具备其它的额外技能做铺垫,例如熟悉Java多线程编程,因为NIO编程涉及到Reactor模式,你必须对多线程和网路编程非常熟悉,才能编写出高质量的NIO程序;
  3. 可靠性能力补齐,工作量和难度都非常大。例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等等,NIO编程的特点是功能开发相对容易,但是可靠性能力补齐工作量和难度都非常大;
  4. JDK NIO的BUG,例如臭名昭著的epoll bug,它会导致Selector空轮询,最终导致CPU 100%。官方声称在JDK1.6版本的update18修复了该问题,但是直到JDK1.7版本该问题仍旧存在,只不过该bug发生概率降低了一些而已,它并没有被根本解决。

2.4 Netty服务器端

先导入倚赖:

<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty</artifactId>
	<version>3.3.0.Final</version>
</dependency>
package nio.netty;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;

import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Auther: 洺润Star
 * @Date: 2020/3/10 15:19
 * @Description:netty服务端
 */
class ServerHandler extends SimpleChannelHandler {
    /**
     * 通道关闭的时候触发
     */
    @Override
    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        System.out.println("channelClosed");
    }

    /**
     * 通道关闭的时候触发(必须是已经建立了连接才会触发)
     */
    @Override
    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        super.channelDisconnected(ctx, e);
        System.out.println("channelDisconnected");
    }

    /**
     * 捕获异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
        super.exceptionCaught(ctx, e);
        System.out.println("exceptionCaught");

    }

    /**
     * 接受消息
     */
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        super.messageReceived(ctx, e);
//		System.out.println("messageReceived");
        System.out.println("服务器端收到客户端消息:"+e.getMessage());
        //回复内容
        ctx.getChannel().write("你好"+e.getMessage());
    }
}

public class NettyServer {
    public static void main(String[] args) {
        //1.创建服务类对象
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //2.创建两个线程池分别监听端口和nio
        ExecutorService boos = Executors.newCachedThreadPool();
        ExecutorService worker = Executors.newCachedThreadPool();
        //3.设置工厂添加两个线程池
        serverBootstrap.setFactory(new NioServerSocketChannelFactory(boos,worker));
        //4.设置管道工厂
        serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline pipeline = Channels.pipeline();
                //将数据转换为string类型.
                pipeline.addLast("decoder", new StringDecoder());
                pipeline.addLast("encoder", new StringEncoder());
                pipeline.addLast("serverHandler", new ServerHandler());
                return pipeline;
            }
        });
        //5.绑定端口号
        serverBootstrap.bind(new InetSocketAddress(8080));
        System.out.println("netty server启动....");
    }
}

现在如果在主方法结尾在加上这样一段代码:

  while (true){
      try {
          Thread.sleep(1000);
          System.out.println("每隔一秒打印");
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
  }

启动后使用浏览器访问,就会发现服务端对客户端的监听不会造成阻塞,服务端不仅能正常接收到浏览器的请求,输出语句也可以正常打印,由此证明netty框架是非阻塞的。

2.5 Netty客户端

package nio.netty;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;

import java.net.InetSocketAddress;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Auther: 洺润Star
 * @Date: 2020/3/10 15:31
 * @Description:netty客户端
 */

class ClientHandler extends SimpleChannelHandler {


    /**
     * 通道关闭的时候触发
     */
    @Override
    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        System.out.println("channelClosed");
    }

    /**
     * 通道关闭的时候触发(必须是已经建立了连接才会触发)
     */
    @Override
    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        super.channelDisconnected(ctx, e);
        System.out.println("channelDisconnected");
    }

    /**
     * 捕获异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
        super.exceptionCaught(ctx, e);
        System.out.println("exceptionCaught");

    }

    /**
     * 接受消息
     */
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        super.messageReceived(ctx, e);
//		System.out.println("messageReceived");
        System.out.println("服务器端向客户端回复内容:"+e.getMessage());
        //回复内容
//		ctx.getChannel().write("好的");
    }

}
public class NettyClient {
    public static void main(String[] args) {
        System.out.println("netty client启动...");
        // 1. 创建客户端类
        ClientBootstrap clientBootstrap = new ClientBootstrap();
        // 2. 创建两个线程池监听端口和nio
        ExecutorService boos = Executors.newCachedThreadPool();
        ExecutorService worker = Executors.newCachedThreadPool();
        //3.设置工厂
        clientBootstrap.setFactory(new NioClientSocketChannelFactory(boos, worker));
        clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() {

            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline pipeline = Channels.pipeline();
                // 将数据转换为string类型.
                pipeline.addLast("decoder", new StringDecoder());
                pipeline.addLast("encoder", new StringEncoder());
                pipeline.addLast("clientHandler", new ClientHandler());
                return pipeline;
            }
        });
        //连接服务端
        ChannelFuture connect = clientBootstrap.connect(new InetSocketAddress("127.0.0.1", 8080));
        Channel channel = connect.getChannel();
        System.out.println("client start");
        Scanner scanner=new Scanner(System.in);
        while (true){
            System.out.println("请输输入内容:");
            channel.write(scanner.next());
        }
    }
}

启动服务端和客户端,客户端输入消息,服务端回复消息:
在这里插入图片描述
在这里插入图片描述
如果连接后停止客户端或服务端程序就会打印如下信息:
在这里插入图片描述

Java NIO与Netty网络编程 Java NIO和Netty都是网络编程中的重要技术。Java NIO提供了非阻塞I/O操作的能力,使得开发高性能网络应用成为可能;而Netty则是一个基于Java NIO的高性能网络应用框架,它封装了Java NIO的复杂性,提供了更易于使用的API和丰富的功能。在实际应用中,应根据具体需求和项目特点选择合适的技术,并结合最佳实践进行优化和实现。 阅读详情

相关推荐

Netty与NIO

BIO,NIO,Netty简介,BIO,AIO,NIO的区别,NIO的Buffer缓冲区,通道,以及处理java.nio.BufferOverflowException异常!欢迎指出错误!

编程小白养成手记 2805

NIO 与 Netty

NIO 什么是 NIO NIO全称Non Blocking IO,同步非阻塞IO框架。服务器实现模式为一个线程可以处理多个请求(连接),客户端发送的连接请求都会注册到多路复用器selector上,多路复用器轮询到连接有IO请求就进行处理 为什么用 NIO 常见的网络服务中,如果每一个客户端都维持一个与登陆服务器的连接。那么服务器将维护多个和客户端的连接以出来和客户端的contnect 、read、write ,特别是对于长链接的服务,有多少个c端,就需要在s端维护同等的IO连接。这对服务器来说

m0_50180963的博客 1306

Socket,NIO,Netty介绍

1. Socket回顾与I/0模型 1.1 Socket网络编程回顾 1.1.1 Socket概述 Socket,套接字就是两台主机之间逻辑连接的端点。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。 Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。 它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议端口。 1.1.2

kitty_hi的博客 1257

什么是NIO,什么是Netty

本文简单介绍了NIO和Netty的概念、特点和区别,并给出了一些示例和插图。希望对你有所帮助。

islautao的博客 1519

专栏总结java8:Socket编程nio—netty快速入门和运行原理

专栏总结java8:Socket编程 nio

黄规速博客:学如逆水行舟,不进则退 899

大麦网抢票软件工具开发系列(一)

前言《大麦网》都知道吧,就是那个被网友声称“大麦网你卖啥了?”票务平台。近期有听到朋友说《大麦网》的票很难抢,基本上都是说:“哎哟喂,被挤爆啦,请稍后重试!”,也不知道《大麦网》...

架构文摘 1万+

netty系列之:NIO和netty详解

文章目录简介NIO常用用法NIO和EventLoopGroupNioEventLoopGroupSelectorProviderSelectStrategyFactoryRejectedExecutionHandlerEventLoopTaskQueueFactoryNioEventLoop总结 简介 netty为什么快呢?这是因为netty底层使用了JAVA的NIO技术,并在其基础上进行了性能的优化,虽然netty不是单纯的JAVA nio,但是netty的底层还是基于的是nio技术。 nio是JDK1.

程序那些事 6433

从Pikachu靶场实战解析越权漏洞:原理、攻击与防御

本文通过Pikachu靶场实战详细解析越权漏洞的原理、攻击方式与防御策略。文章深入探讨水平越权和垂直越权的危害,结合代码示例展示漏洞利用过程,并提供代码层和架构层的立体化防御方案,帮助开发者有效防范这一Web安全隐形杀手。

weixin_29325007的博客 356

异步非阻塞框架 netty 与 nio

第一次深入了解nio,都会感觉非常的难理解阻塞与非阻塞,同步和异步阻塞,非阻塞,下面来看看吧 一、nio 和 netty 是什么? 1、Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始) 2、 Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。 3、主要...

ws - 兮的博客空间 1733

(SCADA)监控与数据采集系统

SCADA应用于监控和采集数据来控制工业过程软件。它通过收集和传输实时数据,帮助操作员监视和控制各种设备和过程。

软件技术的专栏 4541

告别OLE!Delphi操作Excel的3种轻量级方案横向评测(FlexCel/XLSReadWriteII/LibXL)

本文深入评测了Delphi操作Excel的三种轻量级方案:FlexCel、XLSReadWriteII和LibXL。通过技术架构、API设计、性能测试和实战案例的全面对比,帮助开发者选择最适合的工具,提升Excel文件处理效率,告别传统OLE方案的依赖和性能问题。

onion的博客 928

NIO与Netty

异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。channels为epoll_array,epoll_ctl事件轮询,有时间放入就绪事件列表中。, AIO 也就是 NIO 2,是NIO 的改进版 NIO 2。标准使用selector多路复用(一个线程处理多个通路的链接)就绪事件列表(epoll_wait做等待)netty主从reactor高并发线程模型。redis高并发线程模型是如何实现的。NIO(非阻塞io)

weixin_40303757的博客 930

【路由交换】思科5506防火墙三区域互通

思科 5506 inside outside dmz 互通

baidu_22774701的博客 6203

Java-NIO高级编程与Netty入门概述

NIO同步阻塞与同步非阻塞 BIO与NIO IO(BIO)和NIO区别:其本质就是阻塞和非阻塞的区别 阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,就会一直等待,直到传输完毕为止。 非阻塞概念:应用程序直接可以获取已经准备就绪好的数据,无需等待。 IO为同步阻塞形式,NIO为同步非阻塞形式,NIO并没有实现异步,在JDK1.7后升级NIO库包,支持异步非阻塞 同学模型NIO2.0(AIO) BIO:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端

魔法革1996 345

用逻辑分析仪实测EM4095:125kHz RFID耳标解码的电压与脉宽玄学

本文通过逻辑分析仪实测EM4095芯片,深入解析125kHz RFID耳标解码中的电压与脉宽关联现象。揭示了供电电压对曼彻斯特编码脉宽的影响规律,并提供了一套可落地的调试方法论,包括信号链路解析、逻辑分析仪配置技巧及系统级稳定性提升方案,帮助开发者解决解码不稳定问题。

weixin_30629653的博客 328

[P4V]Perforce(P4V)使用教程

1.前言 Perforce SCM System是一款构建于可伸缩客户/服务器结构之上的软件配置管理工具。仅仅应用TCP/IP,开发人员就能够通过多种Perforce客户端(几种平台的GUI、WEB、或命令行)访问Perforce服务器。Perforce能够被快速和容易地部署,即使对大型或分布式的站点,也只要求最小限度的管理。Perforce可以使用在50多个操作系统中,它包括版...

元直的博客 2万+

太厉害了!从NIO一直学到Netty

Netty Netty就是基于NIO的网络(Socket)客户端服务端实现框架,它简化了TCP/UDP客户端服务端编程,开发人员不再关注底层的Socket读取和写入,而且Netty提供了不少的handler(如http、mqtt、redis协议等)实现,简化了基于网络协议的编程复杂度。 Netty 采用 NIO 而非 AIO 的理由 1.Netty 不看重 Windows 上的使用,在 Linux 系统上,AIO 的底层实现仍使用 EPOLL,没有很好实现 AIO,因此在性能上没有明显的优势,而且

Java圈全能架构师的博客 584

移植Google Gemini Nano到RK3588 NPU,实现高效边缘推理

在嵌入式 AI 开发中,大家常常会遇到模型在硬件平台上运行时出现性能瓶颈的问题,比如推理速度慢、功耗过高,这严重影响了应用的实时性和稳定性 ,导致性能瓶颈,无法满足如智能安防、工业检测等场景的实时性需求。为了解决这些问题,我们可以将轻量模型移植到具有强大算力的硬件平台上。本文将手把手教你将 Google Gemini Nano(或类似轻量模型)移植到 RK3588 NPU,充分发挥 RK3588 NPU 的 6Tops 算力,实现高效的模型推理,提升嵌入式系统的 AI 处理能力。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 293

Netty——BIO、NIO 与 Netty

本文介绍了 BIO、NIO 与 Netty,并对比了 NIO 和 Netty 的区别。

qq_61350148的博客 1217

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

还在为Java的NIO编程发愁吗?也许你该接触下Netty网络编程了(从Netty环境搭建到Netty入门案例)

Netty是业界最流行的NIO框架之一,它的健壮性、功能、性能和可扩展性在同类框架中都是首屈一指的,它已经得到了成百上千的商用项目的验证。本文是Netty网络编程的入门教程,从Netty开发环境的搭建到Netty入门实例编程。 Netty入门教程1. Netty开发环境搭建1.1. 下载Netty的jar包1.2 搭建Netty工程1.3 使用Maven工程2. Netty编程入门案例2.1 Netty服务端编程2.2 Netty客户端编程2.3 运行结果 1. Netty开发环境搭建 环境配置: J.

LMR的博客 1万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Netty入门 -- 什么是Netty?

通俗易懂,一文让你搞懂Netty~

wanghuichen的博客 2328

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【Netty】NIO与Netty核心概念

Netty核心概念

qq_43745578的博客 1278

Java网络编程演进:从NIO到Netty的UDP实践全解析

通过对比NIO和Netty的实现,我们可以清楚地看到Netty在简化网络编程、提高开发效率和性能方面的优势。Netty不仅封装了复杂的NIO操作,还提供了丰富的功能和优化措施,使得开发高性能网络应用变得更加容易。随着技术的不断发展,保持学习和实践的态度,将帮助我们在网络编程领域不断提升。无论是使用NIO还是Netty,核心都是要理解网络编程的基本原理。

阿水的博客 3615

Netty快速入门

Netty快速入门

Zhangsama1的博客 8987
上一篇: NIO编程基础
下一篇: Netty高级
金心靖晨
博客等级 码龄9年 460粉丝 211原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值