Netty笔记0----NIO例子

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 阅读详情

Netty笔记0----NIO例子

1.客户端:

  • 启动类

public class TimeClient {

    /**
     * @param args
     */
    public static void main(String[] args) {

        int port = 10000;
        new Thread(new TimeClientHandler("127.0.0.1", port), "TimeClient-001").start();
    }
}

 

  • 实现类

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class TimeClientHandler implements Runnable {

    private String host;
    private int port;

    private Selector selector;
    private SocketChannel socketChannel;

    private volatile boolean stop;

    public TimeClientHandler(String host, int port) {
        this.host = host;
        this.port = port;
        try {
            selector = Selector.open();
            socketChannel = SocketChannel.open();
            socketChannel.configureBlocking(false);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public void run() {
        try {
            doConnect();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
        while (!stop) {
            try {
                selector.select(1000);
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                Iterator<SelectionKey> it = selectedKeys.iterator();
                SelectionKey key = null;
                while (it.hasNext()) {
                    key = it.next();
                    it.remove();
                    try {
                        handleInput(key);
                    } catch (Exception e) {
                        if (key != null) {
                            key.cancel();
                            if (key.channel() != null)
                                key.channel().close();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        }

        // 多路复用器关闭后,所有注册在上面的Channel和Pipe等资源都会被自动去注册并关闭,所以不需要重复释放资源
        if (selector != null) {
            try {
                selector.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void handleInput(SelectionKey key) throws IOException {

        if (key.isValid()) {
            // 判断是否连接成功
            SocketChannel sc = (SocketChannel) key.channel();
            if (key.isConnectable()) {
                if (sc.finishConnect()) {
                    sc.register(selector, SelectionKey.OP_READ);
                    doWrite(sc);
                } else {
                    System.exit(1);// 连接失败,进程退出
                }
            }
            if (key.isReadable()) {
                ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                int readBytes = sc.read(readBuffer);
                if (readBytes > 0) {
                    readBuffer.flip();
                    byte[] bytes = new byte[readBuffer.remaining()];
                    readBuffer.get(bytes);
                    String body = new String(bytes, "UTF-8");
                    System.out.println("Now is : " + body);
                    this.stop = true;
                } else if (readBytes < 0) {
                    // 对端链路关闭
                    key.cancel();
                    sc.close();
                }
            }
        }

    }

    private void doConnect() throws IOException {
        // 如果直接连接成功,则注册到多路复用器上,发送请求消息,读应答
        if (socketChannel.connect(new InetSocketAddress(host, port))) {
            socketChannel.register(selector, SelectionKey.OP_READ);
            doWrite(socketChannel);
        } else {
            socketChannel.register(selector, SelectionKey.OP_CONNECT);
        }
    }

    private void doWrite(SocketChannel sc) throws IOException {
        byte[] req = "QUERY TIME ORDER".getBytes();
        ByteBuffer writeBuffer = ByteBuffer.allocate(req.length);
        writeBuffer.put(req);
        writeBuffer.flip();
        sc.write(writeBuffer);
        if (!writeBuffer.hasRemaining()) {
            System.out.println("Send order 1 server succeed.");
        }
    }

}

 

2.服务端:

  • 启动类

public class TimeServer {

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
   int port = 10000;
   MultiplexerTimeServer timeServer = new MultiplexerTimeServer(port);
   new Thread(timeServer, "NIO-MultiplexerTimeServer-001").start();
    }
}
  • 实现类

public class MultiplexerTimeServer implements Runnable {

    private Selector selector;

    private ServerSocketChannel servChannel;

    private volatile boolean stop;

    /**
     * 初始化多路复用器、绑定监听端口
     *
     * @param port
     */
    public MultiplexerTimeServer(int port) {
        try {
            selector = Selector.open();
            servChannel = ServerSocketChannel.open();
            servChannel.configureBlocking(false);
            servChannel.socket().bind(new InetSocketAddress(port), 1024);
            servChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("The time server is start in port : " + port);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public void stop() {
        this.stop = true;
    }
    public void run() {
        while (!stop) {
            try {
                selector.select(1000);
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                Iterator<SelectionKey> it = selectedKeys.iterator();
                SelectionKey key = null;
                while (it.hasNext()) {
                    key = it.next();
                    it.remove();
                    try {
                        handleInput(key);
                    } catch (Exception e) {
                        if (key != null) {
                            key.cancel();
                            if (key.channel() != null) {
                                key.channel().close();
                            }
                        }
                    }
                }
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }

        // 多路复用器关闭后,所有注册在上面的Channel和Pipe等资源都会被自动去注册并关闭,所以不需要重复释放资源
        if (selector != null) {
            try {
                selector.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void handleInput(SelectionKey key) throws IOException {

        if (key.isValid()) {
            // 处理新接入的请求消息
            if (key.isAcceptable()) {
                // Accept the new connection
                ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                SocketChannel sc = ssc.accept();
                sc.configureBlocking(false);
                // Add the new connection to the selector
                sc.register(selector, SelectionKey.OP_READ);
            }
            if (key.isReadable()) {
                // Read the data
                SocketChannel sc = (SocketChannel) key.channel();
                ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                int readBytes = sc.read(readBuffer);
                if (readBytes > 0) {
                    readBuffer.flip();
                    byte[] bytes = new byte[readBuffer.remaining()];
                    readBuffer.get(bytes);
                    String body = new String(bytes, "UTF-8");
                    System.out.println("The time server receive order : "
                            + body);
                    String currentTime = "QUERY TIME ORDER"
                            .equalsIgnoreCase(body) ? new java.util.Date(
                            System.currentTimeMillis()).toString()
                            : "BAD ORDER";
                    doWrite(sc, currentTime);
                } else if (readBytes < 0) {
                    // 对端链路关闭
                    key.cancel();
                    sc.close();
                }
            }
        }
    }

    private void doWrite(SocketChannel channel, String response)
            throws IOException {
        if (response != null && response.trim().length() > 0) {
            byte[] bytes = response.getBytes();
            ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
            writeBuffer.put(bytes);
            writeBuffer.flip();
            channel.write(writeBuffer);
        }
    }
}

3.总结:原生JDK的NIO步骤繁琐,使用复杂

Netty 权威指南笔记(二):Java NIO 和 Netty 对比 Netty 是业界流行的 NIO 框架之一,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都说首屈一指的,也已经得到了成百上千商用项目的验证。Netty 框架都有什么优点呢? 1. API 使用简单,开发门槛低。 2. 功能强大,预置多种编解码功能,支持多种主流协议。 3. 定制能力强,可以通过 ChannelHandler 对通信框架灵活扩展。 4. 性能高。 5. 成熟稳定,社区活跃,已经修复了 Jav 阅读详情

相关推荐

Netty与NIO

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

编程小白养成手记 2805

1-2 非阻塞I/O 和基于Netty的客户端与服务端通信

非阻塞I/O Client.java import java.io.*; import java.net.Socket; public class Client { public static void main (String ... argas){ ClientHandle clientHandle = null; try { ...

H_crab的博客 332

Netty介绍及NIO详解

Netty简介 Netty是一个异步、基于事件驱动的网络应用框架 BIO、NIO、AIO的简介 应用场景 分布式系统中各节点远程过程调用(RPC:Dubbo) 游戏服务器 Hadoop通信 NIO 三大组件 NIO三大组件:Selector、Channel、Buffer 一个Channel对应一个Buffer,一个Selector管理多个Channel,一个线程对应一个Selecto...

dzyls的笔记 9433

Netty之NIO

空转”指的是:Selector 频繁触发写事件,但你没有实际业务要处理(即没有数据需要写),这会造成CPU 空耗,浪费资源。本质上就是:写事件一直在通知你,但你啥也不用干,程序在“白忙活”。

qq_45101876的博客 1869

Java NIO与Netty网络编程

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

shejizuopin的博客 1143

Netty和JDK源码来看Netty的NIO和JDK的NIO有什么不同

JDK底层提供了NIO实现,在Linux环境会调用内核epoll。 但是Netty通过JNI的方式提供了Native Socket Transport,为什么Netty要自己搞一套NIO呢? 这篇文章带你从jdk的源码和Netty的源码角度来分析为什么Netty要这么做。 1.先看EpollEventLoop实现 Native.epollCtlAdd(epollFd.intV...

深度Java 2819

Netty从0到1系列之NIO

NIO核心思想与组件摘要 传统BIO采用阻塞式流模型,存在线程资源浪费问题。NIO通过三大核心组件实现高效I/O处理: Channel:双向通信通道(文件/网络),支持非阻塞模式 Buffer:数据容器,通过position/limit/capacity机制实现灵活读写 Selector:多路复用器,单线程可监控数千通道的IO事件

编程技术圈 1460

408计算机复试专业课问答汇总

408计算机复试专业课问答汇总

weixin_45930223的博客 3698

Netty学习之NIO基础

Channel与BufferJava NIO系统的核心通道(Channel)和缓冲区(Buffer)。通道表示打开到 IO 设备(例如:文件、套接字)的连接。若需要使用 NIO 系统,需要获取用于连接 IO 设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理简而言之,通道负责传输,缓冲区负责存储常见的Channel有以下四种,其中FileChannel主要用于文件传输,其余三种用于网络通信Buffer有以下几种,其中使用较多的是ByteBufferByteBuffer。

qq_29012499的博客 1453

计算机三级考试嵌入式系统重点精简汇总

第一章 嵌入式系统概论 1.1.1嵌入式系统 (1)特点:(1)专用性;(2)隐蔽性;(3)资源受限;(4)高可靠性;(5)实时性;(6)软件固化。 (2)应用:(1)冰箱、洗衣机、电饭煲、空调、摄影机、DVD播放器等;(2)数控机床、飞机、汽车、电梯、X光机、血压计等;(3)电话机、传真机、打印机、pos机、GPS导航仪、路由器等。 1.1.2嵌入式系统组成与分类 (1)逻辑组成:硬件和软件,分为处理器、存储器、I|0设备与I|O接口,数据总线; (2)处理器:分为主处理器(CPU)和协处

chemkrik的博客 1万+

openmediavault(OMV) (1)安装部署

EXT3(Third Extended File System): EXT3 是 Linux 中广泛使用的日志文件系统,是 EXT2 文件系统的升级版本。这里可以根据自己的需求进行设置,目前只设置了自动登出为1天,为方便后续配置使用,其他设置可根据自己的具体需求进行设置。通过cd 命令进入到我们的raid存储中,通过ls发现里面没有任何的数据,因为我们的raid存储中还未创建任何数据。我的系统要安装在100G的磁盘上,故选择100G的磁盘,实际可以根据具体情况选择。

Monster✺◟(∗❛ัᴗ❛ั∗)◞✺的博客 2168

【Netty4核心原理③】【 Netty 与 NIO 之前世今生】

本系列内容为阅读《Netty4 核心原理》一书内容总结,内容存在个人删改,仅做个人笔记使用。第三章 Netty 与 NIO 之前世今生</</</</TODO。

猫吻鱼的博客 1327

dify upload存在SSRF漏洞

Dify 是一个用于构建 AI 应用程序的开源平台。

nnn2188185的博客 1478

什么是NIO,什么是Netty

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

islautao的博客 1519

【实战篇导读】四足机器人运动控制导读

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对四足机器人运动运动控制系统及相关算法做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章主要介绍了波士顿spot机器人的发展历史、四足机器人的硬件系统及电机执行器组成包括硬件系统、关节电机执行器,机载传感器机处理器及电气连接等。概述了四足机器人规划控制、感知、定位及局部地图的相关算法方向。

qq_35635374的博客 678

lammps 案例in文件汇总

进阶案例: 聚乙烯和石墨烯界面pull out模拟代码 反应力场reax/c设置方法及案例解析 石墨烯热导率模拟代码(NEMD方法) 圆锥形SiC纳米磨削单晶硅源代码 高熵合金FeNiCrCoCu纳米压痕模拟代码 fix indent命令实现纳米摩擦及摩擦力计算 Fe原子辐照轰击多层石墨烯模拟代码 铝基石墨烯复合物压缩变形in文件源代码 石墨烯自动卷曲到Fe纳米线模拟源代码 铝/石墨烯复合物结晶过程lammps模

lammps_jiayou的博客 9445

【Netty】NIO与Netty核心概念

Netty核心概念

qq_43745578的博客 1278

详细解读经典跨模态对齐技术Q-Former代码

介绍BLIP2的博客层出不穷,介绍Q-Former的博客也不少,但是详细解读Q-Former代码的博客很少。这篇博客希望以代码为基础,讲明白Q-Former的原理和核心思想,并详细解读一些值得注意的细节。希望读者们能从这一经典技术中朝花夕拾,得到启发。

沉迷单车的追风少年 2459

nio框架netty在项目中的应用

背景: 省分短信发送每天都差不多要1000W条上下,遇到特殊节假日和政府通告时量会更大!boss系统中存放的是短信发送内容,而真正完成发送短信指令动作是的华为方做的短厅,这么大的通信量选择了netty来完成数据传输并自定义了一套基于netty的SGIP协议进行通信; 省分boss系统—>短信营业厅(); 基本知识 2.1 TCP/IP网络协议 网上很多有关这个协议的解释,自行googl

不断出发,永无抵达! 1万+

[明道云] -基础教学1- 创建第一个工作表:从 0 到实用

明道云工作表相当于数据库表,是存储业务数据的核心组件。创建工作表主要有两种方式:1)从空白新建,通过添加字段(最多200个)、设置属性、配置表单样式;2)从Excel导入,需选择sheet、配置字段映射。创建后系统自动生成默认视图,支持多种视图形式(看板/日历等)。建议设置合适的标题字段和关联关系,初学者可在一小时内完成基础应用搭建。后续可扩展权限控制、工作流自动化等功能。

每日出拳老爷子的博客 556

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Java NIO框架Netty(二)netty5例子,代码详解

这是一个netty快速入门的例子,也是我的学习笔记,比较简单,翻译于官方的文档整理后把所有代码注释放在每一行代码中间,简单明了地介绍一些基础的用法。首页这是基于netty5的例子,如果需要使用请依赖netty5的包。maven引用方式<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</arti

lichch的博客 3054

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

NIO笔记(二)Netty框架

Netty框架 前面我们学习了Java为我们提供的NIO框架,提供使用NIO提供的三大组件,我们就可以编写更加高性能的客户端/服务端网络程序了,甚至还可以自行规定一种通信协议进行通信。 NIO框架存在的问题 但是之前我们在使用NIO框架的时候,还是发现了一些问题,我们先来盘点一下。 客户端关闭导致服务端空轮询 可能在之前的实验中,你发现了这样一个问题: 当我们的客户端主动与服务端断开连接时,会导致READ事件一直被触发,也就是说selector.select()会直接通过,并且是可读的状态,但是我们发现实

qq_25928447的博客 1913

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

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

NIO 与 Netty

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

m0_50180963的博客 1306

springboot整合NIO框架netty

小编在网上找到的一个大神编写的NIO框架demo,githua地址: https://codeload.github.com/marquisXuan/netty 下面是其中一个最简单的小测试: 1.添加依赖pom.xml <dependency> <groupId>io.netty</groupId> ...

qq_41426326的博客 6821

Java NIO、Reactor、Netty

文章目录1.NIO概述2.Channel3.Buffer4.Selector5.内存映射文件 1.NIO概述   NIO包括:Channel、Buffer、Selector   NIO是面向缓冲区的,传统IO是面向流的;传统IO基于字节流、字符流进行操作。NIO基于Channel和Buffer进行操作,数据总是从Channel读到Buffer,从Buffer写到Channel。传统IO是阻塞的,N...

ZXW601498616的博客 1105
上一篇: 输入流InputStream的read(byte b[], int off, int len)方法的使用
下一篇: Netty笔记1----第一个netty例子
过河的小卒子
博客等级 码龄10年 39粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值