`
h140465
  • 浏览: 21903 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

NIO的Selector

 
阅读更多

使用Selector实现简单的Sever:

package nio;

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 NIOServer {
	
	private Selector selector;
	
	private ByteBuffer buffer = ByteBuffer.allocate(1024);
	
	private ByteBuffer lBuffer = ByteBuffer.allocate(32);
	
	private ByteBuffer[] bbs = new ByteBuffer[]{buffer,lBuffer};
	
	public NIOServer(int port) throws Exception{
		init(port);
	}

	public  void init(int port) throws Exception{
		selector = Selector.open();//首先生成一个Selector
		ServerSocketChannel schanel = ServerSocketChannel.open();//创建一个ServerSocketChannel
		schanel.configureBlocking(false);//设置为非阻塞
		schanel.bind(new InetSocketAddress(port));//绑定端口号
		schanel.register(selector, SelectionKey.OP_ACCEPT);//在Selector上注册一个接受事件
	}
	
	public void start() throws Exception{
		while(true){
			int num = selector.select();
			System.out.println("数量:"+num);
			Iterator<SelectionKey> ite=selector.selectedKeys().iterator();
			while(ite.hasNext()){
				SelectionKey key = ite.next();
				handle(key);
				ite.remove();//需要自己手动remove事件
			}
		}
	}
	
	public void handle(SelectionKey key) throws Exception{
		if(key.isAcceptable()){//接受到一个客户端请求
			System.out.println("接受到一个请求");
			ServerSocketChannel s = (ServerSocketChannel)key.channel();
			SocketChannel socket = s.accept();//获取一个客户端连接SocketChannel
			socket.configureBlocking(false);
			socket.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);//在客户端连接上注册READ和WRITE事件
		}else
		if(key.isReadable()){
			System.out.println("接受到一个read请求");
			buffer.clear();
			SocketChannel socket = (SocketChannel)key.channel();
			
			int r = socket.read(buffer);
			System.out.println("读取长度:"+r);
			if(-1==r){
				socket.close();
				key.cancel();
			}
			System.out.println(new String(buffer.array(),"utf-8"));
			
		}
	}
	public static void main(String[] args) throws Exception {
		NIOServer server = new NIOServer(9999);
		server.start();
	}
}

 客户端代码:

package socket;

import java.io.DataOutputStream;

import mySocket.SocketWrapper;

public class Client {

	public static void main(String[] args) {
		SocketWrapper client;
		try {
			client = new SocketWrapper("127.0.0.1", 9999);
			DataOutputStream out = client.getOutputStream();
			out.writeInt(1);
			String s = new String("师妃暄的脸上méng着一层淡淡的薄纱,说不出来的朦胧和神秘,目注从营帐中行出的祝yù研");
			byte[] ss = s.getBytes("utf-8");
			System.out.println(ss.length);
//			out.writeInt(ss.length);
			out.write(ss);
			out.flush();
//			OutputStreamWriter writer = new OutputStreamWriter(client.getOutputStream());
//			writer.write("你是谁啊啊啊啊");
//			writer.flush();
			
			
			
			out.close();
			client.close();
			System.out.println("GAME OVER!!!");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}
 

代码存在一些问题,服务端会调用多次read事件,且会把整个buffer(1024)全部打印出来

 

以下是修改之后的代码:

package nio;

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;
import java.util.Set;

public class NIOServer {
	
	private Selector selector;
	
	private ByteBuffer buffer = ByteBuffer.allocate(1024);
	
	private ByteBuffer lBuffer = ByteBuffer.allocate(32);
	
	private ByteBuffer[] bbs = new ByteBuffer[]{buffer,lBuffer};
	
	public NIOServer(int port) throws Exception{
		init(port);
	}

	public  void init(int port) throws Exception{
		selector = Selector.open();//首先生成一个Selector
		ServerSocketChannel schanel = ServerSocketChannel.open();//创建一个ServerSocketChannel
		schanel.configureBlocking(false);//设置为非阻塞
		schanel.bind(new InetSocketAddress(port));//绑定端口号
		schanel.register(selector, SelectionKey.OP_ACCEPT);//在Selector上注册一个接受事件
	}
	
	public void start() throws Exception{
		while(true){
			int num = selector.select();
//			System.out.println("数量:"+num);
			Iterator<SelectionKey> ite=selector.selectedKeys().iterator();
			while(ite.hasNext()){
//			Set<SelectionKey> selectionKeySet = selector.selectedKeys();
//			for (SelectionKey selectionKey : selectionKeySet) {
				SelectionKey key = ite.next();
//				ite.remove();
				selector.selectedKeys().remove(key);
				handle(key);
			}
//			selectionKeySet.clear();
		}
	}
	
	public void handle(SelectionKey key) throws Exception{
		if(key.isAcceptable()){//接受到一个客户端请求
			System.out.println("接受到一个请求");
			ServerSocketChannel s = (ServerSocketChannel)key.channel();
			SocketChannel socket = s.accept();//获取一个客户端连接SocketChannel
			socket.configureBlocking(false);
			socket.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);//在客户端连接上注册READ和WRITE事件
		}else
		if(key.isReadable()){
//			System.out.println("接受到一个read请求");
			buffer.clear();
			SocketChannel socket = (SocketChannel)key.channel();
			
			int r = socket.read(buffer);
//			System.out.println("读取长度:"+r);
			if(r<1){
				socket.close();
				key.cancel();
			}else
			System.out.println(new String(buffer.array(),0,r,"utf-8"));
			
		}
	}
	public static void main(String[] args) throws Exception {
		NIOServer server = new NIOServer(8888);
		server.start();
	}
}

 

分享到:
评论

相关推荐

    java nio Selector的使用-客户端

    Selector是Java NIO中的核心组件之一,它允许单个线程处理多个通道(channels)的读写事件,极大地提高了服务器的并发能力。本篇文章将深入探讨如何在Java NIO中使用Selector处理客户端的I/O请求。 首先,我们需要...

    Java Nio selector例程

    我研究并实现的Java Nio selector例子。java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server...

    Java NIO Selector选择器简介.pdf

    ### Java NIO Selector选择器详解 #### 一、Selector概览及作用 **Selector** 是 Java NIO (New I/O) 框架中的一个重要组成部分,主要用于检测一个或多个 **NIO Channel** 的状态,包括但不限于可读、可写、可连接...

    Java NIO Selector用法详解【含多人聊天室实例】

    Selector是Java NIO中的关键组件,用于实现多路复用,即单个线程可以监控多个通道(Channel)的事件,例如读取、写入或连接等。 1. Java NIO Channel与Buffer Channel代表I/O操作的源或目标,如文件、套接字等。...

    java nio Selector的使用-服务器端

    Selector是Java NIO中的核心组件,用于监听多个通道的事件,如连接建立、数据可读、写空等。在服务器端,Selector的应用尤为重要,因为它可以实现单线程处理多个客户端连接,从而提高系统的并发能力。 Selector的...

    NIO详细介绍channle,buffer,Selector

    ### NIO:Channel、Buffer与Selector详解 #### 一、NIO概述 NIO(Non-blocking I/O,非阻塞I/O)是Java为了解决传统阻塞式I/O效率低下的问题而引入的一种新的I/O操作模式。NIO通过引入Channel、Buffer以及Selector...

    Java-NIO类库Selector机制解析.docx

    "Java NIO Selector 机制解析" Java NIO(New I/O)类库是Java 1.4版本以后引入的新一代I/O机制,相比传统的I/O机制,NIO提供了高效、异步、多路复用的I/O操作模式。Selector机制是NIO类库中的一种核心机制,用于...

    Java_NIO-Selector.rar_java nio_selector

    Selector是Java NIO框架中的核心组件,它使得单个线程能够管理多个通道(Channels),从而提高系统资源利用率并优化性能。下面我们将详细探讨Java NIO中的Selector机制。 1. **Selector的作用** Selector的主要功能...

    Java NIO——Selector机制解析三(源码分析)

    本文将深入探讨Java NIO中的Selector机制,并通过源码分析来理解其实现原理。 Selector机制是Java NIO中的核心组件,它允许单线程同时监控多个通道(Channels)的状态变化,例如连接就绪、数据可读或可写等。这种...

    Java_NIO类库Selector机制解析.doc

    Java_NIO类库Selector机制解析.docJava_NIO类库Selector机制解析.docJava_NIO类库Selector机制解析.docJava_NIO类库Selector机制解析.doc

    java selector类的用法举例

    ### Java NIO Selector 类的用法详解 #### 一、引言 在Java网络编程中,随着并发连接数量的增长,传统的基于`ServerSocket`和`Socket`的方式在处理大量连接时变得效率低下。为此,Java引入了非阻塞I/O模型(Non-...

    ScalableIOJava(NIO如何实现Selector模式的).pdf

    标题《Scalable IO in Java》和描述表明本文档讨论了Java中的可伸缩网络I/O编程,并且特别聚焦于NIO的Selector模式。NIO,全称为Non-blocking I/O(非阻塞I/O),是Java提供的一种用于处理网络通信或文件I/O的编程...

    JavaNIO库Selector机制解析.docx

    JavaNIO库Selector机制解析.docx

    Java-NIO之Selector.doc

    Java NIO(非阻塞I/O)中的Selector是一个核心组件,它允许单个线程处理多个通道(channels)上的I/O事件。Selector的角色就像一个交通指挥员,能够监控多个通道并决定哪个通道准备好进行读写操作,从而提高系统的...

    java基于NIO选择器Selector的多人聊天室

    Java NIO(非阻塞I/O)是一种在Java中处理I/O操作的高效方式,它引入了选择器(Selector)的概念,使得一个单独的线程可以监控多个输入输出通道(Channels),大大提高了并发处理能力。在这个"java基于NIO选择器...

    【IT十八掌徐培成】Java基础第27天-03.NIO-Selector.zip

    本教程由知名IT教育专家徐培成讲解,主要聚焦于NIO中的Selector组件,它是NIO系统中的核心部分,用于管理多个通道(Channels)并监听它们的事件。 Selector允许单线程处理多个通道,极大地提高了程序的并发性能。在...

    【IT十八掌徐培成】Java基础第27天-04.NIO-Selector-Server-Client.zip

    课程中的视频文件"Java基础第27天-04.NIO-Selector-Server-Client.avi"很可能包含了实际的代码演示和讲解,帮助学习者直观理解Selector的工作原理以及如何在Java中实现NIO服务器和客户端的交互。通过观看视频和动手...

    深入了解java NIO之Selector(选择器)

    "深入了解 Java NIO 之 Selector(选择器)" Java NIO(Non-Blocking I/O)中,Selector(选择器)是一种重要的组件,它提供了选择执行已经就绪的任务的能力,使得多元 I/O 成为可能。在 Java 中,Selector 是一种...

    java mina框架全套

    5. **NIOSelector**:Mina利用Java的NIO选择器,可以高效地管理大量并发连接,减少了线程资源的消耗,提高了系统性能。 Mina的应用场景广泛,包括但不限于: - **Web服务器**:构建高性能的HTTP服务器,提供静态...

Global site tag (gtag.js) - Google Analytics