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. 【bzoj4987】Tree 树形dp

    Description 从前有棵树. 找出K个点A1,A2,-,Ak. 使得∑dis(AiAi+1),(1<=i<=K-1)最小. Input 第一行两个正整数n,k,表示数的顶点数和需要 ...

  2. 【bzoj3796】Mushroom追妹纸 hash/sa+kmp+二分

    Description Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意--写情书.考虑到自己的表达能力,Mushroom决定不手写情书.他从网上找到了两篇极佳的情书, ...

  3. P3705 [SDOI2017]新生舞会 01分数规划+费用流

    $ \color{#0066ff}{ 题目描述 }$ 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴. 有\(n\)个男生和\(n\)个女生参加舞会买一个男生和一个女生一 ...

  4. 品味ZooKeeper之Watcher机制_2

    品味ZooKeeper之Watcher机制 本文思维导图如下: 前言 Watcher机制是zookeeper最重要三大特性数据节点Znode+Watcher机制+ACL权限控制中的其中一个,它是zk很 ...

  5. Unity3d 中 将远程 MySQL 数据库转换为本地 Sqlite

    1.创建MySQL2Sqlite脚本mysql2sqlite.sh:(代码地址:https://gist.github.com/esperlu/943776) #!/bin/sh # Converts ...

  6. gitlab 服务器的搭建与使用全过程(二)

    <gitlab操作手册 1.0 > 此手册适用于 Mac 计算机 第一步:根据从管理员得到的用户名和初始密码登陆并修改密码.新密码不得少于8个字符 第二步:在自己的电脑上创建密钥,并提交提 ...

  7. 安装python发行版本,并用conda来管理Environments,Python,packages

    简介:anaconda指的是一个开源的python发行版本,其包含了conda.Python等180多个科学包及其依赖项. 因为包含了大量的科学包,Anaconda 的下载文件比较大(约 515 MB ...

  8. class __init__()

    python 先定义函数才能调用 类是客观对象在人脑中的主观映射,生产对象的模板,类相当于盖房的图纸,生产工具的模具 模板 类:属性.方法 __init__() 这个方法一般用于初始化一个类但是 当实 ...

  9. [USACO12FEB]牛的IDCow IDs 一题多解(求二进制中有k个1 ,第n大的数)

    题目: FJ给他的奶牛用二进制进行编号,每个编号恰好包含K 个"1" (1 <= K <= 10),且必须是1开头.FJ按升序编号,第一个编号是由K个"1&q ...

  10. BZOJ - 1497 最小割应用

    题意:基站耗费成本,用户获得利益(前提是投入成本),求最大获利 最小割的简单应用,所有可能的收益-(消耗的成本/失去的收益),无穷大边表示冲突,最小割求括号内的范围即可 #include<ios ...