1、用 nio 通讯的过程我用以下情景给你模拟:1. 学校(ServerSocketChannel) 2. 学校教务处(Selector)3. 老师 (ServerSocket ) 4. 学生 (SocketChannel) 5. 员工号/学生号(SelectionKey)学校:相当于我们的网络应用程序,一旦学校启动,学校就不停止,不断运行,直到学期结束; 要启动学校就要: ServerSocketChannel ssc= ServerSocketChannel.open();/新建 NIO 通道 ssc.configureBlocking( false );/使通道为非阻塞 老师:相当于服务端的
2、 Socket,一个老师对应多个学生,多个学生向老师请教,老师会一一做出回答。而学校要正常运营当然少不了老师,所以在开学之前,必须先聘请专业的老师来任教 ServerSocket ss = ssc.socket();/创建基于 NIO 通道的 socket 连接 /新建 socket 通道的端口 ss.bind(new InetSocketAddress(“127.0.0.1“,SERVERPORT); 学校教务处: 老师都有了,但是需要有部门对老师和学生做统一的管理, 如果你去一个学校找一个人,实在是找不到,你可以告诉教务处,那个人是学生还是老师,是老师的话员工编号老师姓名的多少,是学生的话
3、学号和姓名是多少,教务处就会找到告诉你他在哪里。 /将 NIO 通道选绑定到选择器,当然绑定后分配的主键为 skey SelectionKey skey = ssc.register( selector, SelectionKey.OP_ACCEPT ); ssc 注册了选择器后,其下的老师 ServerSocket 就也入了员工册了。所以老师的编号就是skey 学生:学校、老师、教务处都有了,现在就可以招生了! 如果有学生来报名: while(true)/除非学期结束,否则一直等待学生 int num = selector.select();/获取通道内是否有选择器的关心事件, 意思是有多少
4、学生报告 if(num 0) System.out.println(“bytesEchoed:“+bytesEchoed); echoBuffer.flip(); System.out.println(“limet:“+echoBuffer.limit(); byte content = new byteechoBuffer.limit(); echoBuffer.get(content); String result=new String(content); doPost(result,sc); /相应老师会去做回答的,细节自己去写吧 echoBuffer.clear(); it.remov
5、e(); /任务完成,记得上面也是一样,要 remove 掉,否则下一次又来一次任务,就死循环了 catch(Exception e) 补充你的补充: ssc.register( selector, SelectionKey.OP_ACCEPT ); 这个方法是把 ssc 注册绑定到选择器 selector 这样下次你想找 ssc 或者判断一个对象是不是ssc 就可以通过 selector 来查找,查找是通过判断 ssc 的 key 得到的。 至于第二个参数SelectionKey.OP_ACCEPT 你可以理解成 ssc 的 key 类型或者操作权限 如果 ssc 是学校老师,那么绑定成功后
6、 老师就拥有了 OP_ACCEPT 的权限或者说他的 key 类型是SelectionKey.OP_ACCEPT Accept 是接受的意思,这是不是很像 socket 编程里的 accept()方法呢? 是的,没错,我们正是通过这个参数给了老师招生和带学生来注册的权限。 而学生呢? 他拥有的权限为 SelectionKey.OP_READ 表示有收发读取消息的权限,即问问题的权限,因此他不能帮别的学生注册。 所以你回到上面仔细看看 while 结构体里面做了判断如下: if (key.readyOps() 看,这里只给他 OP_READ,而不是 Accept 哦 另一个 if else if(key.readyOps() & SelectionKey.OP_READ)= SelectionKey.OP_READ) /很明显,这是这学生,因为所有带 OP_READ 的人都是前面由招生办老师带过来注册过的。