Java Socket NIO详解(转)
java选择器(Selector)是用来干嘛的?
2009-01-12 22:21jsptdut | 分类:JAVA相关 | 浏览8901次
如题,不要贴api的,上面的写的我看不懂希望大家能给我个通熟易懂的例子
还有ServerSocketChannel这个类,java.nio这个包里的东西,我看api也不懂~
哎,恼火呀
又是你呵~
ssc.register( selector, SelectionKey.OP_ACCEPT );
这个方法的第二个参数是什么意思呀?还有这个SelectionKey.OP_READ
api这样说:用于套接字接受操作的操作集位。 不懂~~~ 呵呵,我来告诉你吧,至于例子代码在我的回答记录中有。你自己翻来去看,是用nio给一个学生写的BBS聊天室。 在用nio通讯的过程我用以下情景给你模拟:
1. 学校(ServerSocketChannel)
2。 学校教务处(Selector)
3。 老师 (ServerSocket )
4。 学生 (SocketChannel)
5。 员工号/学生号(SelectionKey) 学校:相当于我们的网络应用程序,一旦学校启动,学校就不停止,不断运行,直到学期结束;
要启动学校就要:
ServerSocketChannel ssc= ServerSocketChannel.open();//新建NIO通道
ssc.configureBlocking( false );//使通道为非阻塞 老师: 相当于服务端的Socket,一个老师对应多个学生,多个学生向老师请教,老师会一一做出回答。而学校要正常运营当然当不了老师,所以在开学之前,必须先聘请专业的老师来任教
ServerSocket ss = ssc.socket();//创建基于NIO通道的socket连接
//新建socket通道的端口
ss.bind(new InetSocketAddress("127.0.0.1",SERVERPORT)); 学校教务处: 老师都有了,但是需要有部门对老师和学生做统一的管理, 如果你去一个学校找一个人,实在是找不到,你可以告诉教务处,那个人是学生还是老师,是老师的话员工编号老师姓名的多少,是学生的话学号和姓名是多少,教务处就会找到告诉你他在哪里。
//将NIO通道选绑定到择器,当然绑定后分配的主键为skey
SelectionKey skey = ssc.register( selector, SelectionKey.OP_ACCEPT );
ssc注册了选择器后,其下的老师ServerSocket就也入了员工册了。所以老师的编号就是skey 学生: 学校、老师、教务处都有了,现在就可以招生了!
如果有学生来报名: while(true){//除非学期结束,否则一直等待学生
int num = selector.select();//获取通道内是否有选择器的关心事件, 意思是有多少学生报告
if(num<1){continue; }
Set selectedKeys = selector.selectedKeys();//获取通道内关心事件的集合 ,这里的集合就是老师和学生的编号集合,如果key是学生的,那就是老学生来问问题,如果key是老师的,那就是招生办的老师带着一个新生来注册
Iterator it = selectedKeys.iterator();
while (it.hasNext()) {//遍历每个key (学生key和老师key)
.......
}
.....
} 既然有学生来报告,那有两种可能,一种是招生老师带着新生来注册的,一种是老生来问问题的。
上面的while (it.hasNext()) 体可以这样写: while (it.hasNext()) {//遍历每个事件
try{
SelectionKey key = (SelectionKey)it.next(); //先得到这个学生的编号key //判断是新生报道还是老生问问题
if ((key.readyOps() & SelectionKey.OP_ACCEPT)
== SelectionKey.OP_ACCEPT) {
//这是招生老师的Key说明是新生注册,先找到招生老师,再由招生老师找到新生,就可以给新生注册学号了
ServerSocketChannel serverChanel = (ServerSocketChannel)key.channel(); //通过key把学校和老师找到了
//从serverSocketChannel中创建出与客户端的连接socketChannel 有了老师才有学生,不可能我教计算机的,来一个想学李小龙的都让他报名
SocketChannel sc = serverChanel.accept(); //学生报名成功
sc.configureBlocking( false );
// 把新连接注册到选择器,新生被接收后给注册个新学号
SelectionKey newKey = sc.register( selector,
SelectionKey.OP_READ ); //注册学号成功,并分配学生的权限
it.remove(); //新生注册任务完成了,呵呵
System.out.println( "Got connection from "+sc );
}else
//读客户端数据的事件,此时有客户端发数据过来,客户端事件 这是老学生来问问题了。
if((key.readyOps() & SelectionKey.OP_READ)== SelectionKey.OP_READ){
// 读取数据 ,接受学生的问题
SocketChannel sc = (SocketChannel)key.channel(); //通过学号知道是谁问的问题 //下面接受问题
int bytesEchoed = 0;
while((bytesEchoed = sc.read(echoBuffer))> 0){
System.out.println("bytesEchoed:"+bytesEchoed);
}
echoBuffer.flip();
System.out.println("limet:"+echoBuffer.limit());
byte [] content = new byte[echoBuffer.limit()];
echoBuffer.get(content);
String result=new String(content);
doPost(result,sc); //相应老师会去做回答的,细节自己去写吧
echoBuffer.clear();
it.remove(); //任务完成,记得上面也是一样,要remove掉,否则下一次又来一次任务,就死循环了
}
}catch(Exception e){}
}
} 补充你的补充: ssc.register( selector, SelectionKey.OP_ACCEPT );
这个方法是把ssc注册绑定到选择器selector 这样下次你想找ssc或者判断一个对象是不是ssc就可以通过selector来查找,查找是通过判断ssc的key得到的。
至于第二个参数SelectionKey.OP_ACCEPT 你可以理解成ssc的key类型或者操作权限
如果 ssc是学校老师,那么绑定成功后 老师就拥有了OP_ACCEPT的权限或者说他的key类型是SelectionKey.OP_ACCEPT
Accept是接受的意思,这是不是很像socket编程里的 accept()方法呢? 是的,没错,我们正是通过这个参数给了老师招生和带学生来注册的权限。 而学生呢?
他拥有的权限为SelectionKey.OP_READ 表示有收发读取消息的权限,即问问题的权限,因此他不能帮别的学生注册。 所以你回到上面仔细看看while结构体里面做了判断如下: if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {...} 很明显,拥有Accept权限的人只可能是老师,那老师有什么事会找教务处? 那肯定就是他是招生办的,招到一个学生来报名来注册了。
然后,马上给这个新连上来的客户端分配了一个key
SelectionKey newKey = sc.register( selector,
SelectionKey.OP_READ ); 看,这里只给他OP_READ,而不是Accept哦 另一个if
else
if((key.readyOps() & SelectionKey.OP_READ)== SelectionKey.OP_READ){ //很明显,这是这学生,因为所有带OP_READ的人都是前面由招生办老师带过来注册过的。 还有不明白吗?
提问者评价
谢谢了,讲得很明白~本想给你加分的,只是我分不多了
Java Socket NIO详解(转)的更多相关文章
- java Socket用法详解(转)
在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器 ...
- 【转】JAVA Socket用法详解
一.构造Socket Socket的构造方法有以下几种重载形式: (1)Socket() (2)Socket(InetAddress address, int port)throws UnknownH ...
- Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制
Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制 JAVA 中原生的 socket 通信机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.co ...
- Java网络编程和NIO详解开篇:Java网络编程基础
Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...
- Java网络编程和NIO详解8:浅析mmap和Direct Buffer
Java网络编程与NIO详解8:浅析mmap和Direct Buffer 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NI ...
- Java网络编程和NIO详解9:基于NIO的网络编程框架Netty
Java网络编程和NIO详解9:基于NIO的网络编程框架Netty 转自https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introd ...
- Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理
Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...
- Java网络编程和NIO详解6:Linux epoll实现原理详解
Java网络编程和NIO详解6:Linux epoll实现原理详解 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO h ...
- Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO
Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO Java 非阻塞 IO 和异步 IO 转自https://www.javadoop.com/post/nio-and-aio 本系 ...
随机推荐
- Mysql 主从数据库
MYSQL主从数据库同步备份配置 一.准备 用两台服务器做测试: Master Server: 172.16.0.180/Linux/MYSQL 5.1.41 Slave Server: 172.16 ...
- php 批量下载文件
public function batchDownload() { $filename = 'tmp.zip'; $zipName = date('YmdHi') . '.zip'; $files = ...
- Win7 VS2017编译PBR渲染引擎google filament
按照官方说明 https://github.com/google/filament 前置工具包 Windows 10 SDKVisual Studio 2017Clang 6Python 3.7Git ...
- git遇到的问题-- Another git process seems to be running in this repository
执行git add .时,报错 fatal: Unable to create '/Users/lily/ForWork/forReBaomai/bm-fe/.git/index.lock': Fil ...
- MySQL 多表结构的创建与分析
=====================多对一===================== create table press( id int primary key auto_increment, ...
- 洛谷 p2440木材加工
#include <iostream>#include <cstring>using namespace std;const int N = 1e5 + 100;int a[N ...
- openXML向Word插入表
表是 Word 中的另一类型的块级内容,它是以行和列排列的一组段落(以及其他块级内容). Word 中的表格通过 tbl 元素定义,该元素类似于 HTML <表格>标记. 表元素指定文档中 ...
- php中测试运行的时间,从而选择得出优化程序
对于新手来说,优化代码的习惯十分重要, 测试运行的时间,从而得出最好的一个 <?php $t1=microtime(true); //获取程序1,开始的时间 程序1(代码...) $t2=m ...
- SolrCloud的搭建与稳定性测试
转载请注明出处:http://www.cnblogs.com/wubdut/p/7573738.html 一.集群搭建 1. zookeeper搭建(版本:3.4) 1.1 zoo.cfg配置文件: ...
- OC对象,自动释放池,OC与C语言的区别
在C语言中,编程都是面向过程的编程,每一个代码块都严格按照从上至下的顺序执行,在代码块之间同样也是这样, 但是在OC中往往不是这样,OC和C++.java等语言一样,都是面向对象的编程语言,在代码的执 ...