欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java nio 编程学习 一

程序员文章站 2022-04-24 10:51:17
...

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