多个SocketChannel注册Selector统一管理

SocketChannel、ServerSocketChannel与Selector的实际案例 一个关于SocketChannel、ServerSocketChannel、Selector的综合案例 立即下载
虽然我们可以自己处理每一个Socket事件,比如读写数据,不过更常规的方式是注册一个选择器。这个选择器侦听着数据的变化事件。 每个注册的通道都有自己的SelectionKey,用这个可以区分到底是哪个通道产生了事件。

看代码
  1. package net.java2000.nio;
  2. import java.io.IOException;
  3. import java.net.InetSocketAddress;
  4. import java.nio.ByteBuffer;
  5. import java.nio.channels.SelectionKey;
  6. import java.nio.channels.Selector;
  7. import java.nio.channels.SocketChannel;
  8. import java.util.Iterator;
  9. /**
  10.  * 多个SocketChannel注册Selector。
  11.  * 
  12.  * @author 赵学庆,Java世纪网(java2000.net)
  13.  * 
  14.  */
  15. public class SocketChannelSelector {
  16.   public static SocketChannel createSocketChannel(String hostName, int port)
  17.       throws IOException {
  18.     SocketChannel sChannel = SocketChannel.open();
  19.     sChannel.configureBlocking(false);
  20.     sChannel.connect(new InetSocketAddress(hostName, port));
  21.     return sChannel;
  22.   }
  23.   // 2个连接注册的选择器关键字
  24.   static SelectionKey key1;
  25.   static SelectionKey key2;
  26.   public static void main(String[] args) {
  27.     // 1个选择器,注册2个Socket 通道
  28.     Selector selector = null;
  29.     try {
  30.       // 创建选择器
  31.       selector = Selector.open();
  32.       // 创建2个通道
  33.       SocketChannel sChannel1 = createSocketChannel("163.net", 25);
  34.       SocketChannel sChannel2 = createSocketChannel("mail.youkuaiyun.com", 25);
  35.       // 注册选择器,侦听所有的事件
  36.       key1 = sChannel1.register(selector, sChannel1.validOps());
  37.       key2 = sChannel2.register(selector, sChannel1.validOps());
  38.     } catch (IOException e) {
  39.     }
  40.     // 等待事件的循环
  41.     while (true) {
  42.       try {
  43.         // 等待
  44.         selector.select();
  45.       } catch (IOException e) {
  46.         break;
  47.       }
  48.       // 所有事件列表
  49.       Iterator<SelectionKey> it = selector.selectedKeys().iterator();
  50.       // 处理每一个事件
  51.       while (it.hasNext()) {
  52.         // 得到关键字
  53.         SelectionKey selKey = it.next();
  54.         // 删除已经处理的关键字
  55.         it.remove();
  56.         try {
  57.           // 处理事件
  58.           processSelectionKey(selKey);
  59.         } catch (IOException e) {
  60.           // 处理异常
  61.           selKey.cancel();
  62.         }
  63.       }
  64.     }
  65.   }
  66.   public static void processSelectionKey(SelectionKey selKey) throws IOException {
  67.     ByteBuffer buf = ByteBuffer.allocateDirect(1024);
  68.     // 确认连接正常
  69.     if (selKey.isValid() && selKey.isConnectable()) {
  70.       // 得到通道
  71.       SocketChannel sChannel = (SocketChannel) selKey.channel();
  72.       // 是否连接完毕?
  73.       boolean success = sChannel.finishConnect();
  74.       if (!success) {
  75.         // 异常
  76.         selKey.cancel();
  77.       }
  78.     }
  79.     // 如果可以读取数据
  80.     if (selKey.isValid() && selKey.isReadable()) {
  81.       // 得到通道
  82.       SocketChannel sChannel = (SocketChannel) selKey.channel();
  83.       if (sChannel.read(buf) > 0) {
  84.         // 转到最开始
  85.         buf.flip();
  86.         while (buf.remaining() > 0) {
  87.           System.out.print((char) buf.get());
  88.         }
  89.         // 也可以转化为字符串,不过需要借助第三个变量了。
  90.         // buf.get(buff, 0, numBytesRead);
  91.         // System.out.println(new String(buff, 0, numBytesRead, "UTF-8"));
  92.         // 复位,清空
  93.         buf.clear();
  94.       }
  95.     }
  96.     // 如果可以写入数据
  97.     if (selKey.isValid() && selKey.isWritable()) {
  98.       // 得到通道
  99.       SocketChannel sChannel = (SocketChannel) selKey.channel();
  100.       // 区分2个侦听器的关键字
  101.       // 我这里只写一次数据。
  102.       if (!s1 && key1.equals(selKey)) {
  103.         System.out.println("channel1 write data..");
  104.         buf.clear();
  105.         buf.put("HELO localhost/n".getBytes());
  106.         buf.flip();
  107.         sChannel.write(buf);
  108.         s1 = true;
  109.       } else if (!s2 && key2.equals(selKey)) {
  110.         System.out.println("channel2 write data..");
  111.         buf.clear();
  112.         buf.put("HELO localhost/n".getBytes());
  113.         buf.flip();
  114.         sChannel.write(buf);
  115.         s2 = true;
  116.       }
  117.     }
  118.   }
  119.   // 判断已经写过数据的标志
  120.   static boolean s1 = false;
  121.   static boolean s2 = false;
  122. }

一个运行的效果
channel1 write data..
220 Coremail SMTP(Anti Spam) System (163net[040302])
250 bjfee_app2
channel2 write data..
220 youkuaiyun.com ESMTP "can't tell you"
250 youkuaiyun.com


结论
  这样做,我们的多个数据通道就可以统一管理,分别处理器读写操作。
奇安信 2025 年护网蓝队初选笔试题(附答案解析) 熬夜为大家整理了 奇安信 2025 年护网蓝队初选笔试题,(关注我我会持续更新)涵盖 SQL 注入、Web 安全、渗透测试、二进制安全 等核心知识点,并附上详细答案解析,助力大家高效备考!12.下列关于虚表指针描述正确的是(1.5分)✅ B. 虚表指针存储的是虚表的首地址❌ A. 任何类对象都存在虚表指针(仅含虚函数的类有)❌ C. 虚表指针位于对象内存空间的起始处(由编译器决定)❌ D. 虚表指针是否存在不影响对象所占内存空间的大小(存在时会增加指针大小)📌 解析:虚表指针(vptr)用于实现多态,指向 阅读详情

相关推荐

从Simulink仿真到DSP28335真机部署:PID闭环控制快速移植指南

本文详细介绍了如何将Simulink中的PID闭环控制算法快速移植到DSP28335嵌入式平台。通过模型与代码映射、浮点与定点数选择、定时器中断配置、物理输出实现以及调试技巧五个关键步骤,帮助工程师高效完成从仿真到真机部署的全过程,特别适合需要实现精确控制的嵌入式开发者。

weixin_42521843的博客 363

Netty(一)基础socketchannel,Buffer,selector黏包 半包解决 实战

non-blockiong io:非阻塞阻塞vs非阻塞。 > selector 就是用来监听事件的 > selector 何时不阻塞 > 1. 客户端发起请求触发 accept > 2.客户端发送数据,客户端正常 异常关闭 ,都会触发read事件,如果数据大于buffer缓冲区 会触发多次读取事件 > 3.channel 可写,会触发write事件 > 4.在linux发生nio bug时也会 > 调用selector.wakeup > 调用seletor.close > selector所在线程in

weixin_45699541的博客 922

STM32驱动四位共阳极数码管实现高精度秒表计时器

本文详细介绍了如何使用STM32驱动四位共阳极数码管实现高精度秒表计时器。项目基于STM32F103C8T6最小系统板,通过定时器中断和GPIO控制,实现0.1秒精度的计时功能,并解析了共阳极数码管的动态扫描原理及按键消抖等关键技术。

n8m7b6v5c4的博客 951

Java nio包SocketChannel详解

SocketChannel 是 Java NIO 中用于实现基于 TCP 协议的套接字通信的通道。在介绍SocketChannel之前先讲下Selector 。

境里婆娑 1215

基于ResNet-50的猫狗分类训练

基于ResNet-50的猫狗分类python训练

weixin_46352497的博客 1004

Python抓取摄像头图像,进行AI识别(一)

本文介绍了如何用Python获取海康威视摄像头的图像并进行AI识别。主要内容包括:1)准备工作,包括摄像头IP设置和密码重置方法;2)使用Python的Requests库通过ISAPI接口获取实时图像;3)示例代码展示如何保存摄像头图像。整个过程为后续AI图像识别提供了基础,通过简单的Python代码即可实现专业监控设备的图像采集功能。

Hahafantuan的博客 1516

网络I/o编程模型6 Nio之Selector以及NIO客户服务通讯

一 selector 1.1 介绍 java的NIO,用非阻塞的IO方式,可以用一个线程,处理多个的客户端连接,就会使用到selector(选择器)。 netty的IO线程NIOEventLoop聚合了selector(选择器,也叫多路复用器),可以同时并发处理成百上千各个客户端连接。 当线程从某客户端socket通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。 只有在连接/通道真正有读写事件发生时,才会进行读写,就大大地减少了系统的开销,并且不必为每个连

健康平安的活着的专栏 1049

基于车辆运动学的规划算法 - Hybrid A*/ State Lattice Planning (前置知识:自行车模型、Dubins、Reeds Shepp、多项式曲线、螺旋曲线)

本文将按顺序讲解基于车辆运动学的规划算法,以及需要的前置知识:自行车模型、Dubins和Reeds Shepp曲线、多项式曲线和螺旋曲线

BigDavid123的博客 4861

[Netty] Selector选择器以及Reactor实现 (七)

Nio中的Selector选择器和Netty的选择器的实现和reactor的netty实现

959 939

优刻得首个「国产千卡智算集群」落地,支持智源千亿大模型训练

在人工智能引领的时代浪潮中,算力已成为技术进步与创新的核心驱动力。面对当下AI算力需求的飙升、高端AI芯片供应受限的挑战,加之OpenAI带来的技术封锁,唯有坚定不移的发展自主可控的国产技术方案,持续壮大国产智算集群规模,才能一路突破围追堵截,进一步促进国产大模型产业生态繁荣。集群还提供了完善高效的软件栈工具,集成多种主流的深度学习编程框架,通过测试验证,确保了对行业领先人工智能模型的高效支持,做到开箱即用,用户可快速投入模型的开发和部署,加速了其在人工智能领域的布局和发展。方面取得了显著成效。

Ucloud_TShare的博客 1474

水气泵控制原理,三角波发生电路,LM331M/TR芯片,高速运放芯片

气泵的控制采用闭环控制,根据气泵的FG反馈信号进行反馈调节,由于气泵的反馈信号是脉冲反馈,即频率改变,占空比不变,即需要通过F/V转换芯片转换成电压信号,变为电压与转速成正比,其电压进入比较器与基准电压进行比较,将比较结果进行运算并进行PWM控制信号。水泵的控制采用闭环控制,根据水泵的pwm信号进行反馈调节,水泵的反馈信号是脉冲反馈,即频率改变,占空比不变,即需要通过F/V转换芯片转换成电压信号,变为电压与转速成反比,其电压进入比较器与基准电压进行比较,将比较结果进行运算并对PWM控制信号。

m0_51010122的博客 2857

Selector通过一个线程管理多个Channel

Selector是NIO中实现I/O多路复用的关键类。Selector实现了通过一个线程管理多个Channel,从而管理多个网络连接的目的。 Channel代表这一个网络连接通道,我们可以将Channel注册到Selector中以实现Selector对其的管理。一个Channel可以注册到多个不同的Selector中。 当Channel注册到Selector后会返回一个SelectionKey...

lusic01的专栏 2235

手把手教你学 GPU KMD”相关内容的专栏简介与目录

本专栏系统讲解GPU内核模式驱动(KMD)开发技术,涵盖四大核心模块:1)GPU驱动架构基础,解析UMD/KMD协同机制;2)KMD核心功能,包括内存管理、命令提交、中断处理等;3)底层硬件交互,详解PCIe/DMA传输、多级页表等;4)实战进阶,结合Linux DRM框架代码分析,探讨GPU虚拟化与性能优化。面向具备OS和C语言基础的开发者,提供从理论到实践的完整学习路径,帮助深入理解图形/计算驱动栈的底层实现原理。

amy_mhd的博客 154

java SocketChannel 网页保存

1:使用SocketChannel的NIO客户机服务器通信示例。(转) http://www.cnblogs.com/likwo/archive/2010/06/29/1767814.html 2: 使用非阻塞ServerSocketChannel、SocketChannel代替ServerSocket和Socket http://blog.csdn.net/maydie1989/ar...

键盘上的舞者 180

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Netty框架之Selector使用详解

谈到Selector的具体使用,那么就要结合BIO,NIO的知识讲解,Selector使用在非阻塞模式NIO场景下,学习NIO之前先要了解BIO原理,下面我们一步步讲解 一.BIO(Blocking-IO)-阻塞IO模式 先来看一下BIO下服务端的代码 public static void main(String[] args) throws Exception { //创建服务端通道 ServerSocketChannel ssc = ServerSocketChannel

TheWayForDream 1777

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

java代码写selector_javaNIO:选择器--实践 Selector

选择器服务器端代码选择器--理论这篇笔记很多和选择器相关的知识点,下面进入实战,看一下如何写和使用选择器实现服务端Socket数据接收的程序,这也是NIO中最核心、最精华的部分。选择器的优点和注意点:1.在传统io soket进行网络通信的时候,使用的阻塞通道,我们能知道什么时候写什么时候读,因为是阻塞的。但在 nio 引入了非阻塞之后,我们就要知道通道什么时候我们该写,什么时候该读,这点nio内...

weixin_32589387的博客 215

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【Netty源码解读和权威指南】第20篇:Netty EventLoop源码解析(下)—— NioEventLoopGroup内幕

本文摘要:Netty EventLoopGroup源码解析(下)—— NioEventLoopGroup内幕 本文深入解析Netty NioEventLoopGroup的实现原理,通过电商平台真实案例(配置不当导致性能下降56%)揭示合理配置线程数的重要性。文章系统讲解了EventLoopGroup的设计哲学、核心功能及与传统线程池的区别,详细分析了其继承体系与核心API,包括5种创建方式(默认配置、指定线程数、自定义线程工厂等)。通过ASCII图示对比传统线程池与Netty线程模型的差异,强调EventL

xyghehehehe的专栏 252

Java IO之NIO

上篇说了最基础的五种IO模型,相信大家对IO相关的概念应该有了一定的了解,这篇文章主要讲讲基于多路复用IO的Java NIO。 背景 Java诞生至今,有好多种IO模型,从最早的Java IO到后来的Java NIO以及最新的Java AIO,每种IO模型都有它自己的特点,详情请看我的上篇文章[Java IO初探](),而其中的的Java...

weixin_34403693的博客 92

Asyncdb(三):Java NIO

本文由 GodPan 发表在 ScalaCool 团队博客。 上篇说了最基础的五种IO模型,相信大家对IO相关的概念应该有了一定的了解,这篇文章主要讲讲基于多路复用IO的Java NIO。 背景 Java诞生至今,有好多种IO模型,从最早的Java IO到后来的Java NIO以及最新的Java AIO,每种IO模型都有它自己的特点,详情请看我的上篇文章Java IO初探,而其中的的Java NI...

weixin_33809981的博客 106

JavaFX+NIO聊天室第二篇Reactor

设计思路 java BIO进行通信有个弊端就是读取或者写入是阻塞的,Server端必须依次的处理完每个请求。要与多个用户同时通信,那么我们必须对每个请求都开启线程。当并发量大时,线程切换的成本也很大,所以并发量大的应用不适用这种技术。所以我们采用NIO来进行通信。Java NIO是jdk1.4新推出的,它是一种同步非阻塞的I/O模型,也是I/O多路复用模式。它的同步指的是读取或者写入的时候依然是同步的,需要等待程序处理完毕才能返回,另外Selector获取哪些Channel有消息时也是同步等待的。非阻塞是指

jiqiren1994的博客 485

构建Java知识体系:从JVM原理到并发编程的深度解析与实践指南

Java作为一门面向对象的编程语言,其核心在于理解程序如何在Java虚拟机(JVM)中运行。JVM通过内存区域划分(如堆、栈、方法区)和垃圾回收机制管理对象生命周期,这构成了Java程序执行的底层原理。深入理解这些机制,对于编写高性能、稳定的应用具有重要技术价值,尤其是在高并发场景下,能有效避免内存泄漏和性能瓶颈。在实际开发中,集合框架(如HashMap、ConcurrentHashMap)和并发工具(如synchronized、AQS)是构建复杂系统的基石,广泛应用于电商、金融等需要处理大量数据和并发请求

weixin_33898233的博客 409

NIO踩坑和难点,关于Selector和SocketChannel

NIO踩坑和难点,关于Selector和SocketChannel

weixin_46543456的博客 459

selector socketChannel

篇文章对NIO进行了简介,对Channel和Buffer接口的使用进行了说明,并举了一个简单的例子来说明其使用方法。 本篇则重点说明selector,Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。 与selector联系紧密的是ServerS

yuliantao的专栏 985

【JavaNIO】Selector

JavaNIO三大件之一的Selector

Wligt的博客 307
上一篇: 向SocketChannel写入数据并读取返回数据
下一篇: 找到的PageRank等于10的三个站点
老紫竹
博客等级 码龄19年 1万+粉丝 1252原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值