java selector
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的更多相关文章
- Java——Selector
- 【Android XML】Android XML 转 Java Code 系列之 Selector(2)
今天我们要把drawable下的selector的XML文件转换成Java代码.(打包进jar,不依赖apk) 在转换工具中的代码为: https://github.com/SickWorm/Andr ...
- 深入理解Java NIO
初识NIO: 在 JDK 1. 4 中 新 加入 了 NIO( New Input/ Output) 类, 引入了一种基于通道和缓冲区的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存 ...
- NIO的一些相关链接
Architecture of a Highly Scalable NIO-Based Server Scalable IO in Java Tricks and Tips with NIO part ...
- 五种I/O 模式,select、epoll方法的理解,BIO、NIO、AIO理解 相关文章
一.io方式 Linux网络编程 五种I/O 模式及select.epoll方法的理解 web优化必须了解的原理之I/o的五种模型和web的三种工作模式 五种I/O 模式——阻塞(默认IO模式),非阻 ...
- [转]MMORPG服务器架构
MMORPG服务器架构 一.摘要 1.网络游戏MMORPG整体服务器框架,包括早期,中期,当前的一些主流架构2.网络游戏网络层,包括网络协议,IO模型,网络框架,消息编码等.3.网络游戏的场景管理,A ...
- Kafka实战分析(一)- 设计、部署规划及其调优
1. Kafka概要设计 kafka在设计之初就需要考虑以下4个方面的问题: 吞吐量/延时 消息持久化 负载均衡和故障转移 伸缩性 1.1 吞吐量/延时 对于任何一个消息引擎而言,吞吐量都是至关重要的 ...
- IO 概括
# 一.概览 Java 的 I/O 大概可以分成以下几类: - 磁盘操作:File- 字节操作:InputStream 和 OutputStream- 字符操作:Reader 和 Writer- 对象 ...
- Flume实战案例运维篇
Flume实战案例运维篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Flume概述 1>.什么是Flume Flume是一个分布式.可靠.高可用的海量日志聚合系统,支 ...
随机推荐
- js面对对象的几种方式
1.对象的字面量 var obj = {} 2.创建实例对象 var obj = new Object(); 3.构造函数模式 function fn(){}, new fn(); ...
- zabbix 3.0 快速安装文档
下载地址:http://www.zabbix.com/download.php 官方文档:https://www.zabbix.com/documentation/3.0/manual/install ...
- php代码书写习惯优化小结
(1)使用 static 静态方法比普通方法快4倍(2)echo输出快于print(3)连接字符使用 , 代替 .(4)循环之前先取出最大值,而不是在循环里面取值 正确的方法 $max ...
- 6A - Daydreamin
#include <iostream> #include <cstdio> using namespace std; typedef long long ll; ll dp[] ...
- java并发包&线程池原理分析&锁的深度化
java并发包&线程池原理分析&锁的深度化 并发包 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的, ...
- C++_类和动态内存分配5-使用指向对象的指针
再探new和delete new为创建的每一个对象的名称字符串分配存储空间,这是在构造函数中进行的: 析构函数使用delete来释放这些内存. 字符串是一个字符数组,所以析构函数使用的是带中括号的de ...
- Java正则表达式-捕获组
private Set<String> getCodes(String s) { Set<String> resultSet = new HashSet<>(); ...
- 自动生成缓存Key值的CacheKeyHelper
/// <summary> /// CacheKeyHelper /// </summary> public class CacheKeyHelper { /// <su ...
- SSH 项目建立过程
1. 加入 Spring 1). 加入 jar 包 2). 配置 web.xml 文件 <context-param> <param-name>contextConfigLoc ...
- linux下目录、文件显示颜色的设置生效
Centos系统 拷贝/etc/DIR_COLORS文件为当前主目录的 .dir_colors 命令:cp /etc/DIR_COLORS ~/.dir_colors 修改~/.dir_colors中 ...