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. mybatis 学习笔记(三):mapper 代理开发 dao 层

    mybatis 学习笔记(三):mapper 代理开发 dao 层 优势 通过使用mapper 代理,我们可以不需要去编写具体的实现类(使用 getMapper() 方法自动生成),只需编写接口即可, ...

  2. Python学习【第五篇】:面向对象及相关

    面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查是否obj是否是类 cls 的对象 1 2 3 4 5 6 c ...

  3. C++_基础2-复合数据类型

    C语言使用术语“派生类型”,C++对类关系使用术语“派生”.所以就改用“复合类型”. 数组 数组是一种数据格式,能够存储多个同类型的值. 数组声明应指出以下三点: 存储在每个元素中的值的类型: 数组名 ...

  4. i2c设备驱动之设备地址

    第一步:查找设备的数据手册可得到设备的从机地址.读写地址. 很不巧的是我在这里又卡了近一天,由于自己的硬件知识学得相当的那啥,哎,没办法,怨不得别人. 今天终于开窍了!!!!! 在开始条件(S)后,发 ...

  5. [转] SpringBoot RESTful 应用中的异常处理小结

    [From] https://segmentfault.com/a/1190000006749441 SpringBoot RESTful 应用中的异常处理小结 永顺 2016年08月29日发布 赞  ...

  6. .net mvc 用jquery ajax成功后页面跳转。

    $.ajax({ //url: 'http://192.168.0.102/webApiDemo/api/WebApiTest/PostStudentInforOnePara', //url: &qu ...

  7. 基于docker+redis++urlib/request的分布式爬虫原理

    一.整体思路及中心节点的配置 1.首先在虚拟机中运行一个docker,docker中运行的是一个linux系统,里面有我们所有需要的东西,linux系统,python,mysql,redis以及一些p ...

  8. windos下安装mongodb

    一.下载 1. www.mongodb.com/download-center#community2.根据电脑系统下载对应的版本,3.选择zip(解压版本)/msi安装版本4.本文是用的msi(安装版 ...

  9. PIE SDK坐标系选择

    1. 功能简介 坐标系选择可以查看当前图层的坐标系信息和显示其他坐标系的信息,下面将基于PIE SDK介绍如何实现坐标系选择功能. 2. 功能实现说明 2.1. 实现思路及原理说明 第一步 加载图层并 ...

  10. js的apply和call

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...