java nio 编程学习 一
Java.nio中的主要类
ServerSocketChannel:ServerSocket的替代类.
SocketChannel:Socket的替代类
Selector:为ServerSocketChannel监控接受就绪事件,为SocketChannel监控连接就绪,读就绪和写就绪事件
SelectionKey:代表ServerSocketChannel及SocketChannel向Selector注册事件句柄
向SocketChannel和ServerSocketChannel注册事件:
SelectionKey key=serverSocketChannel.register(selector,op)
Op的可选值
对于ServerSocketChannel只有一个事件:
(1)SelectionKye.OP_ACCEPT:接受连接就绪事件,表示至少有了一个客户连接,服务器可以接受这个连接
SocketChannel可能发生3种事件
(1)SelectionKey.OP_CONNECT:连接就为事件,表示客户与服务器的连接已经成功
(2)SelectionKey.OP_WRITE/OP_READ:写的就绪事件,表示已经可以向输出流写数据了SocketChannel提供了接受和发送的方法
可以使用:read(ByteBuffer)write(ByteBuffer)写入写出
ServerSocketChannel类
方法:(PS继承过SelectableChannel类的方法)
(1)open()静态方法获取ServerSocketChannel对象.
(2)accept同ServerSocket,不过获取的是SocketChannel,根据是否阻塞返回null还是阻塞,值得注意的是accept返回的SocketChannel是阻塞模式的使用configureBlocking更改模式
(3)socket() 返回关联的ServerSocket
SocketChannel类
此类是Socket类的替代类
方法:(PS继承过SelectableChannel类的方法)
(1)open() open(SocketAddress)静态方法用来创建SocketChannel对象,第二个重写还会建立于远程服务器的连接.
(2)socket()返回关联的Socket对象
(3)isConnected()是否建立连接
(4)isConnectionPending判断是否正在进行远程连接
(5)connect() 建立远程连接() 根据是否阻塞而不同
(6)finishConnect() 视图完成远程连接
(7)read()读取数据(这个应该是接数据)
(8)write()写数据(这个是发送数据)
声明:
public static int PORT = 8888;
ServerSocketChannel serverChannel;
ServerSocket serverSocket;
Selector selector;
初始化:
// 1. 分配一个 ServerSocketChannel 文件描述符
serverChannel = ServerSocketChannel.open();
// 2. 从 ServerSocketChannel里获取一个对于的 socket
serverSocket = serverChannel.socket();
// 3. 生成一个 Selector
selector = Selector.open();
// 4. 把 socket 绑定到端口上
serverSocket.bind(new InetSocketAddress(iport));
// 5. serverChannel 未非bolck
serverChannel.configureBlocking(false);
// 6. 通过Selector注册ServerSocketChannel: 只能注册 accept
// 而SocketChannel可以注册CONNENCT,READ,WRITE ; register -> validOps
// 在各个子类实现不同
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
开启服务:
while (true) {
try {
// 获得IO准备就绪的channel数量
int n = selector.select();
// 没有channel准备就绪,继续执行
if (n == 0) {
continue;
}
// 用一个iterator返回Selector的selectedkeys
Iterator it = selector.selectedKeys().iterator();
// 处理每一个SelectionKey
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
// 判断是否有新的连接到达
if (key.isAcceptable()) {
// 返回SelectionKey的ServerSocketChannel
ServerSocketChannel server = (ServerSocketChannel) key
.channel();
System.out.println("有连接");
SocketChannel channel = server.accept();
registerChannel(selector, channel, SelectionKey.OP_READ);
doWork(channel);
}
// 判断是否有数据在此channel里需要读取
if (key.isReadable()) {
processData(key);
}
}
// 删除 selectedkeys
it.remove();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
上一篇: netty入门demo
下一篇: 一个demo