netty(二):NIO——处理可写事件
处理可写事件
什么情况下需要注册可写事件?
- 在服务端一次性无法把数据发送完的情况下,需要注册可写事件
- 服务端一次性是否能够把数据全部发送完成取决于服务端的缓冲区大小,该缓冲区不受程序控制
注册可写事件的步骤
-
判断ByteBuffer是否仍有剩余,如果有剩余注册可写事件
ByteBuffer bf = "hello client,welcome"; SocketChannel sc = (SocketChannel) selectionKey.channel(); sc.write(bf); if(bf.hasRemaining){selectionKey.interestOps(SelectionKey.OP_READ + SelectionKey.OP_WRITE);selectionKey.attachment(bf); } -
监听可写事件,判断数据是否写完,数据写完需要
if (key.isWritable()){// 监听可写事件SocketChannel channel = (SocketChannel) key.channel();ByteBuffer byteBuffer = (ByteBuffer) key.attachment();channel.write(byteBuffer);if (!byteBuffer.hasRemaining()) {// 判断数据是否写完// 数据写完,解除对buffer的引用key.attach(null);// 数据写完,不再关注可写事件key.interestOps(key.interestOps() - SelectionKey.OP_WRITE);} }
代码示例
-
客户端
package com.ysf;import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.Charset;public class Client {public static void main(String[] args) throws IOException {SocketChannel sc = SocketChannel.open();sc.connect(new InetSocketAddress("127.0.0.1",11027));sc.write(Charset.defaultCharset().encode("123456\n223456\nhello server\n"));while (true){ByteBuffer allocate = ByteBuffer.allocate(16);sc.read(allocate);allocate.flip();System.out.println(Charset.defaultCharset().decode(allocate));}} } -
服务端
package com.ysf;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.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Iterator; import java.util.Map;public class WriterSelectorServer {public static void handleContent(ByteBuffer byteBuffer){byteBuffer.flip();for (int i = 0;i < byteBuffer.limit();i++){if (byteBuffer.get(i) == '\n'){int length = i + 1 - byteBuffer.position();ByteBuffer allocate = ByteBuffer.allocate(length);for (int j = 0;j<length;j++){allocate.put(byteBuffer.get());}allocate.flip();System.out.println(Charset.defaultCharset().decode(allocate));}}byteBuffer.compact();}public static void main(String[] args) throws IOException {Selector selector = Selector.open();ServerSocketChannel ssc = ServerSocketChannel.open();ssc.configureBlocking(false);ssc.bind(new InetSocketAddress(11027));SelectionKey sscKey = ssc.register(selector, 0, null);sscKey.interestOps(SelectionKey.OP_ACCEPT);while (true){selector.select();Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()){SelectionKey key = iterator.next();iterator.remove();if (key.isAcceptable()){ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();SocketChannel sc = serverSocketChannel.accept();sc.configureBlocking(false);ByteBuffer welcome = Charset.defaultCharset().encode("welcome");sc.write(welcome);Map<String,ByteBuffer> attach = new HashMap<>();ByteBuffer readBuffer = ByteBuffer.allocate(16);attach.put("read",readBuffer);SelectionKey scKey = sc.register(selector, 0, attach);if (welcome.hasRemaining()){attach.put("write",welcome);scKey.interestOps(SelectionKey.OP_READ + SelectionKey.OP_WRITE);}else {scKey.interestOps(SelectionKey.OP_READ);}}else if (key.isReadable()){SocketChannel channel = (SocketChannel) key.channel();Map<String, ByteBuffer> attachment = ((Map<String,ByteBuffer>) key.attachment());ByteBuffer readBuffer = attachment.get("read");int read;try {read = channel.read(readBuffer);} catch (IOException e) {e.printStackTrace();key.cancel();continue;}if (read == -1){key.cancel();}else {handleContent(readBuffer);if (readBuffer.position() == readBuffer.limit()){ByteBuffer newAttachment = ByteBuffer.allocate(readBuffer.capacity() * 2);readBuffer.flip();newAttachment.put(readBuffer);attachment.put("read",newAttachment);}}}else if (key.isWritable()){SocketChannel channel = (SocketChannel) key.channel();Map<String, ByteBuffer> attachment = (Map<String, ByteBuffer>) key.attachment();ByteBuffer byteBuffer = attachment.get("write");channel.write(byteBuffer);if (!byteBuffer.hasRemaining()) {attachment.remove("write");key.interestOps(key.interestOps() - SelectionKey.OP_WRITE);}}}}} }
相关文章:
netty(二):NIO——处理可写事件
处理可写事件 什么情况下需要注册可写事件? 在服务端一次性无法把数据发送完的情况下,需要注册可写事件 服务端一次性是否能够把数据全部发送完成取决于服务端的缓冲区大小,该缓冲区不受程序控制 注册可写事件的步骤 判断ByteBuffer是否仍…...
PHP基本语法解析与应用指南
PHP(Hypertext Preprocessor)是一种广泛应用的开源脚本语言,特别适用于Web开发。本文将深入探讨PHP的基本语法,包括变量、数据类型、运算符、控制流等方面的内容。我们将详细介绍每个主题的基本概念、语法规则和常见应用ÿ…...
ICS PA1
ICS PA1 init.shmake 编译加速ISA计算机是个状态机程序是个状态机准备第一个客户程序parse_argsinit_randinit_loginit_meminit_isa load_img剩余的初始化工作运行第一个客户程序调试:零断点TUI 基础设施单步执行打印寄存器状态扫描内存 表达式求值词法分析递归求值…...
Java学数据结构(4)——散列表Hash table 散列函数 哈希冲突
目录 引出散列表Hash table关键字Key和散列函数(hash function)散列函数解决collision哈希冲突(碰撞)分离链接法(separate chaining)探测散列表(probing hash table)双散列(double hashing) Java标准库中的散列表总结 引出 1.散列表,key&…...
OVRL-V2: A simple state-of-art baseline for IMAGENAV and OBJECTNAV 论文阅读
论文信息 题目:OVRL-V2: A simple state-of-art baseline for IMAGENAV and OBJECTNAV 作者:Karmesh Yadav, Arjun Majumdar, Ram Ramrakhya 来源:arxiv 时间:2023 代码地址: https://github.com/ykarmesh…...
【安全】原型链污染 - Hackit2018
目录 准备工作 解题 代码审计 Payload 准备工作 将这道题所需依赖模块都安装好后 运行一下,然后可以试着访问一下,报错是因为里面没内容而已,不影响,准备工作就做好了 解题 代码审计 const express require(express) var hbs require…...
net.ipv4.ip_forward=0导致docker容器无法与外部通信
在启动一个docker容器时报错: WARNING: IPv4 forwarding is disabled. Networking will not work. 并且,此时本机上的其他容器的网络服务,只能在本机上访问,其他机器上访问不到。 原因: sysctl net.ipv4.ip_forward …...
软考高级系统架构设计师系列论文九十八:论软件开发平台的选择与应用
软考高级系统架构设计师系列论文九十八:论软件开发平台的选择与应用 一、相关知识点二、摘要三、正文四、总结一、相关知识点 软考高级系统架构设计师系列之:面向构件的软件设计,构件平台与典型架构二、摘要 本文讨论选择新软件开发平台用于重新开发银行中间业务系统。银行中…...
Springboot整合WebFlux
一、使用WebFlux入门 WebFlux整合MysqlWebFlux整合ESWebFlus整合MongdbWebFlus整合Redis 1、添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId><version>2.2.1.…...
uniapp 实现地图距离计算
在uniapp中实现地图距离计算可以借助第三方地图服务API来实现。以下是一种基本的实现方式: 注册地图服务API账号:你可以选择使用高德地图、百度地图等提供地图服务的厂商,注册一个开发者账号并获取API密钥。 安装相关插件或SDK:根…...
破除“中台化”误区,两大新原则考核中后台
近年来,“中台化”已成为许多企业追求的目标,旨在通过打通前后台数据和业务流程,提升运营效率和创新能力。然而,在实施过程中,一些误解可能导致“中台化”未能如预期般发挥作用。本文将探讨这些误解,并提出…...
基于YOLOV8模型和Kitti数据集的人工智能驾驶目标检测系统(PyTorch+Pyside6+YOLOv8模型)
摘要:基于YOLOV8模型和Kitti数据集的人工智能驾驶目标检测系统可用于日常生活中检测与定位车辆、汽车等目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用…...
基于Android的课程教学互动系统 微信小程序uniapp
教学互动是学校针对学生必不可少的一个部分。在学校发展的整个过程中,教学互动担负着最重要的角色。为满足如今日益复杂的管理需求,各类教学互动程序也在不断改进。本课题所设计的springboot基于Android的教学互动系统,使用SpringBoot框架&am…...
OpenCV基础知识(9)— 视频处理(读取并显示摄像头视频、播放视频文件、保存视频文件等)
前言:Hello大家好,我是小哥谈。OpenCV不仅能够处理图像,还能够处理视频。视频是由大量的图像构成的,这些图像是以固定的时间间隔从视频中获取的。这样,就能够使用图像处理的方法对这些图像进行处理,进而达到…...
PostgreSQL命令行工具psql常用命令
1. 概述 通常情况下操作数据库使用图形化客户端工具,在实际工作中,生产环境是不允许直接连接数据库主机,只能在跳板机上登录到Linux服务器才能连接数据库服务器,此时就需要使用到命令行工具。psql是PostgreSQL中的一个命令行交互…...
【CSS 画个梯形】
使用clip-path: polygon画梯形 clip-path: polygon使用方式如下: 效果实现 clip-path: polygon 是CSS的属性之一,用于裁剪元素的形状。它可以通过定义一个具有多边形顶点坐标的值来创建一个多边形的裁剪区域,从而实现元素的非矩形裁剪效果。…...
Spring Data Redis
文章目录 Redis各种Java客户端Spring Data Redis使用方式操作字符串类型的数据操作哈希类型数据列表类型集合类型有序集合类型通用类型 Redis各种Java客户端 Java中如何操作redis,这里主讲IDEA中的框架Spring Data Redis来操作redis Jedis是官方推出的,…...
软件测试的方法有哪些?
软件测试 根据利用的被测对象信息的不同,可以将软件测试方法分为:黑盒测试、灰盒测试、白盒测试。 1、白盒测试 1)概念:是依据被测软件分析程序内部构造,并根据内部构造分析用例,来对内部控制流程进行测试…...
Python Qt学习(二)Qt Designer
一开始以为Designer是个IDE,多番尝试之后,发现,是个UI设计工具,并不能在其中直接添加代码。保存之后,会生成一个后缀是UI的文件,再用pyuic5.exe将ui文件转化成py文件。pyuic5 -o 目标py文件 源ui文件...
我的数据上传类操作(以webDAV为例)
在登录处进行初始化: 1.读取配置 GModel.ServerSetin JsonToIni.GetClass<ServerSet>(ConfigFiles.ConfigFile);if (!string.IsNullOrWhiteSpace(GModel.ServerSetin.FTPUser)){OPCommon.NetControls.NetworkShareConnect.connectToShare(GModel.ServerSeti…...
Sketch MeaXure:3步告别设计标注烦恼的TypeScript重构方案
Sketch MeaXure:3步告别设计标注烦恼的TypeScript重构方案 【免费下载链接】sketch-meaxure 项目地址: https://gitcode.com/gh_mirrors/sk/sketch-meaxure Sketch MeaXure是一款基于TypeScript重构的Sketch设计标注插件,专为解决UI设计师与开发…...
茉莉花插件:重塑你的中文文献研究新范式
茉莉花插件:重塑你的中文文献研究新范式 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件,用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 作为一名学术研究者ÿ…...
从百元平板到AIoT:成本极致化下的电子设计哲学与职业未来
1. 从百元平板之争看电子设计的未来走向那天在门洛帕克的星巴克,Vivek Wadhwa迟到了几分钟,一坐下就带着那种即将沸腾的能量感切入正题:“我最近好像总在惹麻烦!”他指的麻烦,是那些关于创新、关于价格、关于行业未来的…...
Sonixd多语言支持详解:国际化(i18n)实现原理和本地化最佳实践
Sonixd多语言支持详解:国际化(i18n)实现原理和本地化最佳实践 【免费下载链接】sonixd A full-featured Subsonic/Jellyfin compatible desktop music player 项目地址: https://gitcode.com/gh_mirrors/so/sonixd Sonixd是一款功能强大的桌面音乐播放器&…...
为什么选择update-golang:5大优势对比传统安装方式
为什么选择update-golang:5大优势对比传统安装方式 【免费下载链接】update-golang update-golang is a script to easily fetch and install new Golang releases with minimum system intrusion 项目地址: https://gitcode.com/gh_mirrors/up/update-golang …...
2026年精选5大小程序定制开发排行榜:赋能数字化转型新体验
导读:随着2026年企业数字化转型加速推进,小程序定制开发作为核心工具,正成为各行各业提升运营效率与用户互动的重要载体。本次深度测评聚焦当前市场中技术实力突出、服务能力全面的五家专业服务商,通过多维度剖析,为寻…...
从混淆矩阵到mIOU:手把手解析语义分割核心评价指标
1. 从像素战场到成绩单:理解混淆矩阵 第一次接触语义分割任务时,我盯着那些五彩斑斓的分割图直发懵——怎么判断这个模型到底好不好?直到导师扔给我一张"混淆矩阵"的表格,才恍然大悟这就像学生时代的考试成绩单。想象你…...
芯粒技术:从封装协同到UCIe标准,破解芯片设计新范式
1. 芯片设计范式的演进:从单片到芯粒在半导体行业摸爬滚打了十几年,亲眼见证了芯片设计从追求单一巨无霸的“单片系统”(SoC)时代,逐渐转向一个更灵活、也更复杂的“乐高积木”时代。这个转变的核心,就是芯…...
Ascend NPU高效无损压缩技术解析与优化
1. 项目概述:Ascend NPU上的高效无损压缩技术在AI模型规模爆炸式增长的今天,模型权重的存储与传输已成为系统瓶颈。以Qwen3-32B模型为例,其65.6GB的权重文件在分布式训练中会产生显著的通信开销。传统CPU/GPU压缩方案如ZipNN(1.5GB/s)和NV-Bi…...
Axure RP实战:从页面跳转到动态交互的五大核心功能详解
1. 页面跳转:让原型"活"起来的起点 第一次用Axure RP做原型时,我最惊讶的不是它华丽的界面,而是点击一个按钮居然能跳转到另一个页面——这简直像变魔术。后来才发现,页面跳转是所有交互设计的基础,就像搭积…...
