java selector使用select轮询注册到selector中的channel,如果有channel准备好注册的事件,select()返回,返回值为可以操作的channel的个数。通过selector.selectedKeys()返回选中的key的集合。遍历集合中所有的key,判断key的事件,进行相应的处理,并从集合中remove掉。

客户端selector的使用逻辑与服务端selector使用逻辑几乎一致。

Server代码中监听了两个端口8888和8889两个端口,并注册到selector中。读取客户端发送的信息,并发送信息到客户端

Client代码向服务器对应的端口号发送信息,并接收服务器端返回的信息

这里我服务端用了channel+selector客户端直接用的socket,可以发送给服务端信息,但接收服务端信息没有接收到(代码没有贴出来)

PS:使用selector+channel可以在一个线程内监听多个channel,下面代码中就监听了两个端口的channel

SelectorServer.java

 import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
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.util.Iterator;
import java.util.Set; /**
* Created by 58 on 2016/11/28.
*/
public class SelectorServer {
public static void main(String args[]){
startServer();
}
public static ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
public static ByteBuffer receiveBuffer = ByteBuffer.allocate(1024); public static void startServer(){
//用两个channel监听两个端口
int listenPort = 8888;
int listenPort1 = 8889;
sendBuffer.put("message from server".getBytes()); try {
//创建serverchannel,绑定对应的端口
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
ServerSocket serverSocket = serverSocketChannel.socket();
InetSocketAddress inetSocketAddress = new InetSocketAddress(listenPort);
serverSocket.bind(inetSocketAddress); //创建第二个channel
ServerSocketChannel serverSocketChannel1 = ServerSocketChannel.open();
ServerSocket serverSocket1 = serverSocketChannel1.socket();
InetSocketAddress inetSocketAddress1 = new InetSocketAddress(listenPort1);
serverSocket1.bind(inetSocketAddress1); //创建selector对象
Selector selector = Selector.open(); //设置channel注册到selector中
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //第二个channel
serverSocketChannel1.configureBlocking(false);
serverSocketChannel1.register(selector, SelectionKey.OP_ACCEPT); System.out.println("start to listen port: " + listenPort);
System.out.println("start to listen port: " + listenPort1); //监听端口
while(true){
int readyChannels = selector.select();
if(readyChannels == 0)
continue;
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while(iterator.hasNext()){
SelectionKey selectionKey = iterator.next();
dealSelectionKey(selector, selectionKey); iterator.remove();
}//while
}//while } catch (IOException e) {
e.printStackTrace();
}
} public static void dealSelectionKey(Selector selector, SelectionKey selectionKey){
try{
//准备好接收新的连接
if(selectionKey.isAcceptable()){
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
SocketChannel clientSocketChannel = serverSocketChannel.accept();
clientSocketChannel.configureBlocking(false);
clientSocketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
System.out.println("channel is ready acceptable");
}
else if(selectionKey.isConnectable()){
selectionKey.channel().register(selector, SelectionKey.OP_READ);
System.out.println("channel is connectable.");
}
else if(selectionKey.isReadable()){
//读去客户端内容
SocketChannel clientSocketChannel = (SocketChannel) selectionKey.channel();
receiveBuffer.clear();
clientSocketChannel.read(receiveBuffer);
selectionKey.interestOps(SelectionKey.OP_WRITE);
System.out.println("message from client is: " + new String(receiveBuffer.array()));
System.out.println("Thread id : " + Thread.currentThread().getId());
}
else if(selectionKey.isWritable()){
//向客户端写数据
SocketChannel clientSocketChannel = (SocketChannel) selectionKey.channel();
sendBuffer.flip();
System.out.println("sendBuffer = " + new String(sendBuffer.array()));
clientSocketChannel.write(sendBuffer);
selectionKey.interestOps(SelectionKey.OP_READ);
System.out.println("channle is writable.");
}//else if
}catch (Exception e){ }
}
}

SelectorClient.java

 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; /**
* Created by 58 on 2016/11/28.
*/
public class SelectorClient {
public static void main(String args[]){
work();
} public static void work(){
int serverPort = 8888;
ByteBuffer sendBuffer = ByteBuffer.wrap("client message".getBytes());
ByteBuffer receiveBuffer = ByteBuffer.allocate(1024);
try {
//创建通道,设置通道注册到selector中
SocketChannel socketChannel = SocketChannel.open();
Selector selector = Selector.open(); socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ | SelectionKey.OP_CONNECT);
socketChannel.connect(new InetSocketAddress("localhost", serverPort));
int executeTimes = 2;
//while
while(executeTimes > 0){
executeTimes--;
int reayChannelNum = selector.select();
if(reayChannelNum == 0){
continue;
}
Set<SelectionKey> setOfSelectionKey = selector.selectedKeys();
Iterator<SelectionKey> iterator = setOfSelectionKey.iterator();
while(iterator.hasNext()){
SelectionKey selectionKey = iterator.next();
SocketChannel socketChannel1 = (SocketChannel) selectionKey.channel();
iterator.remove();
if(selectionKey.isConnectable()){
if(socketChannel1.isConnectionPending()){
socketChannel1.finishConnect();
System.out.println("connection complete.");
socketChannel1.write(sendBuffer);
}
}//if isConnectable
else if(selectionKey.isReadable()){
receiveBuffer.clear();
socketChannel1.read(receiveBuffer);
receiveBuffer.flip();
System.out.println("message from server: " + new String(receiveBuffer.array())); }//else if readable
else if(selectionKey.isWritable()){
sendBuffer.flip();
socketChannel1.write(sendBuffer);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

java selector的更多相关文章

  1. Java——Selector

  2. 【Android XML】Android XML 转 Java Code 系列之 Selector(2)

    今天我们要把drawable下的selector的XML文件转换成Java代码.(打包进jar,不依赖apk) 在转换工具中的代码为: https://github.com/SickWorm/Andr ...

  3. 深入理解Java NIO

    初识NIO: 在 JDK 1. 4 中 新 加入 了 NIO( New Input/ Output) 类, 引入了一种基于通道和缓冲区的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存 ...

  4. NIO的一些相关链接

    Architecture of a Highly Scalable NIO-Based Server Scalable IO in Java Tricks and Tips with NIO part ...

  5. 五种I/O 模式,select、epoll方法的理解,BIO、NIO、AIO理解 相关文章

    一.io方式 Linux网络编程 五种I/O 模式及select.epoll方法的理解 web优化必须了解的原理之I/o的五种模型和web的三种工作模式 五种I/O 模式——阻塞(默认IO模式),非阻 ...

  6. [转]MMORPG服务器架构

    MMORPG服务器架构 一.摘要 1.网络游戏MMORPG整体服务器框架,包括早期,中期,当前的一些主流架构2.网络游戏网络层,包括网络协议,IO模型,网络框架,消息编码等.3.网络游戏的场景管理,A ...

  7. Kafka实战分析(一)- 设计、部署规划及其调优

    1. Kafka概要设计 kafka在设计之初就需要考虑以下4个方面的问题: 吞吐量/延时 消息持久化 负载均衡和故障转移 伸缩性 1.1 吞吐量/延时 对于任何一个消息引擎而言,吞吐量都是至关重要的 ...

  8. IO 概括

    # 一.概览 Java 的 I/O 大概可以分成以下几类: - 磁盘操作:File- 字节操作:InputStream 和 OutputStream- 字符操作:Reader 和 Writer- 对象 ...

  9. Flume实战案例运维篇

    Flume实战案例运维篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Flume概述 1>.什么是Flume Flume是一个分布式.可靠.高可用的海量日志聚合系统,支 ...

随机推荐

  1. loj#6041. 「雅礼集训 2017 Day7」事情的相似度(后缀自动机+启发式合并)

    题面 传送门 题解 为什么成天有人想搞些大新闻 这里写的是\(yyb\)巨巨说的启发式合并的做法(虽然\(LCT\)的做法不知道比它快到哪里去了--) 建出\(SAM\),那么两个前缀的最长公共后缀就 ...

  2. PHP编码技巧

    原则 正确实现功能 执行速度与快 占系统资源少 后期维护方便 编程注意 1.命名很重要 2.适当的使用注释 3.使用一个变量,需要初始化 4.优先使用单引号 $row['id']的效率是$row[id ...

  3. Mysql数据库申请

    前段时间大部门下新成立了一个推广百度OCR.文字识别.图像识别等科技能力在金融领域应用的子部门.因为部门刚成立,基础设施和人力都是欠缺的.当时分到我们部门的任务是抽调一个人做新部门主站前端开发工作.本 ...

  4. flex 实例Demo

    Flex 页面布局 很方便 快捷 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  5. Qt 学习之路 2(40):隐式数据共享

    Qt 学习之路 2(40):隐式数据共享 豆子 2013年1月21日 Qt 学习之路 2 14条评论 Qt 中许多 C++ 类使用了隐式数据共享技术,来最大化资源利用率和最小化拷贝时的资源消耗.当作为 ...

  6. FPGA基础学习(5) -- 时序约束(实践篇)

    目录 1. 理论回顾 2. 时间裕量 3. 最大延迟和最小延迟 4. 案例分析 参考文献: 距离上一篇有关时序的理论篇已经有一段时间了(可以参考博文FPGA时序约束--理论篇),实际上此段时间,甚至到 ...

  7. redis mac安装配置

    去官网下载redis. 解压后 终端cd 至目标文件夹 编译测试: sudo make test 编译安装: sudo make install 输入redis-server启动服务 停止 redis ...

  8. filezilla绑定编辑器

    编辑  - >设置 ->文件格式关联 ->输入需要关联的编辑器的路径

  9. [转]【NODE】用WS模块创建加密的WS服务(WSS)

    [From] https://luojia.me/2015/07/21/%E3%80%90node%E3%80%91%E7%94%A8ws%E6%A8%A1%E5%9D%97%E5%88%9B%E5% ...

  10. 文献综述八:基于JAVA的商品网站的研究

    一.基本信息 标题:基于JAVA的商品网站的研究 时间:2015 出版源:信息技术 文件分类:对java语言的研究 二.研究背景 本文主要介绍了系统的分析,设计和开发的全部过程. 三.具体内容 文献的 ...