Netty学习-02
来源:互联网 发布:网络融资平台靠谱吗 编辑:程序博客网 时间:2024/05/17 21:02
Demon3:
package com.study.netty.test;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.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;public class NIOServerTest {// 通道管理器private Selector selector;/** * 获得一个ServerSocket通道,并对该通道做一些初始化的工作 * * @param port * 绑定的端口号 * @throws IOException */public void initServer(int port) throws IOException {// 获得一个ServerSocket通道ServerSocketChannel serverChannel = ServerSocketChannel.open();// 设置通道为非阻塞serverChannel.configureBlocking(false);// 将该通道对应的ServerSocket绑定到port端口serverChannel.socket().bind(new InetSocketAddress(port));// 获得一个通道管理器this.selector = Selector.open();// 将通道管理器和该通道绑定,并为该通道注册SelectionKey.OP_ACCEPT事件,注册该事件后,// 当该事件到达时,selector.select()会返回,如果该事件没到达selector.select()会一直阻塞。serverChannel.register(selector, SelectionKey.OP_ACCEPT);}/** * 采用轮询的方式监听selector上是否有需要处理的事件,如果有,则进行处理 * * @throws IOException */public void listen() throws IOException {System.out.println("服务端启动成功!");// 轮询访问selectorwhile (true) {// 当注册的事件到达时,方法返回;否则,该方法会一直阻塞selector.select();// 获得selector中选中的项的迭代器,选中的项为注册的事件Iterator<?> ite = this.selector.selectedKeys().iterator();while (ite.hasNext()) {SelectionKey key = (SelectionKey) ite.next();// 删除已选的key,以防重复处理ite.remove();handler(key);}}}/** * 处理请求 * * @param key * @throws IOException */public void handler(SelectionKey key) throws IOException {// 客户端请求连接事件if (key.isAcceptable()) {handlerAccept(key);// 获得了可读的事件} else if (key.isReadable()) {handelerRead(key);}}/** * 处理连接请求 * * @param key * @throws IOException */public void handlerAccept(SelectionKey key) throws IOException {ServerSocketChannel server = (ServerSocketChannel) key.channel();// 获得和客户端连接的通道SocketChannel channel = server.accept();// 设置成非阻塞channel.configureBlocking(false);// 在这里可以给客户端发送信息哦System.out.println("新的客户端连接");// 在和客户端连接成功之后,为了可以接收到客户端的信息,需要给通道设置读的权限。channel.register(this.selector, SelectionKey.OP_READ);}/** * 处理读的事件 * * @param key * @throws IOException */public void handelerRead(SelectionKey key) throws IOException {// 服务器可读取消息:得到事件发生的Socket通道SocketChannel channel = (SocketChannel) key.channel();// 创建读取的缓冲区ByteBuffer buffer = ByteBuffer.allocate(1024);int read = channel.read(buffer);if(read > 0){byte[] data = buffer.array();String msg = new String(data).trim();System.out.println("服务端收到信息:" + msg);//回写数据ByteBuffer outBuffer = ByteBuffer.wrap("OK".getBytes());channel.write(outBuffer);// 将消息回送给客户端}else{System.out.println("客户端关闭");key.cancel();}}/** * 启动服务端测试 * * @throws IOException */public static void main(String[] args) throws IOException {NIOServerTest server = new NIOServerTest();server.initServer(8000);server.listen();}}
以上代码可以在debug下模拟调用过程;
NIO图:
socketIO:
NIO的特点
ServerSocketChannel ServerSocket
SocketChannel Socket
Selector
SelectionKey
NIO的一些疑问
1、客户端关闭的时候会抛出异常,死循环
解决方案
int read = channel.read(buffer);
if(read > 0){
byte[] data = buffer.array();
String msg = new String(data).trim();
System.out.println("服务端收到信息:" + msg);
//回写数据
ByteBuffer outBuffer = ByteBuffer.wrap("好的".getBytes());
channel.write(outBuffer);// 将消息回送给客户端
}else{
System.out.println("客户端关闭");
key.cancel();
}
2、selector.select();阻塞,那为什么说nio是非阻塞的IO?
selector.select()
selector.select(1000);不阻塞
selector.wakeup();也可以唤醒selector
selector.selectNow();也可以立马返还,视频里忘了讲了,哈,这里补上
3、SelectionKey.OP_WRITE是代表什么意思
OP_WRITE表示底层缓冲区是否有空间,是则响应返还true
阅读全文
0 0
- Netty学习-02-SocketChannel
- Netty学习-02
- Netty学习-05-Netty
- Netty----什么是Netty学习
- netty学习
- Netty学习
- Netty学习
- Netty学习
- Netty学习
- netty 学习
- netty学习
- Netty学习
- Netty学习
- Netty学习 netty nio编程
- 【Netty】netty学习笔记一
- Netty自学-Netty学习(一)
- Netty 学习(5) Netty Example--echo
- Netty 学习(8)Netty Example Telnet
- Qt5 文件编码
- 系统地讲述Cookie与Session机制
- 三重循环寻找最长连续字符串相加和为K值倍数的长度
- Leetcode 289. Game of Life
- SpringMVC学习(六)-自定义类型转换器
- Netty学习-02
- Shader的纹理
- XML文件解析
- java创建线程的三种方式及其对比
- poj 4102:宠物小精灵之收服
- 使用SVN进行版本控制
- toString()模板语法研究
- 【学习笔记四】- 用js实现的一些数组操作和算法
- CSS选择器