`
kylinsoong
  • 浏览: 240659 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java Nio Usage Demo & A example of use selectableChannel

阅读更多

Primary purpose of this blog is to use http://kylinsoong.iteye.com/blog/1250681 Listed API, complete a demo application: this application has two part, one is the Server, the other is Client, Client send a message to the Server Side, the Server response the recieved message to Client. as following picture depicted:



 This is Sever side logical sequence, Sever Side Open a ServerSocketChannel, use no-blocking mode, set resueAddress as true, bind IP address "localhost" and port number "8000";

The serverSocketChannel register a OP_ACCEPT Event to a opened Selector, use a look listen-in the OP_ACCEPT Event, while OP_ACCEPT Event occuring, the server retrieve the selection key from key set and deal with the key according to the key's attribute:

if it's a isAcceptable Event, the server side get the Socketchannel through Channel, also set no-blocking is true, register the OP_READ and OP_WRITE Event to the same Selector, came to loop again.

if it's a isReadable Event, Read th e data from channel, output to the console;

if it's a idWriteable Event, Write the echo message to Client Side through the channel.



 The Client Side is much clearer. Firstly, the client side open a SocketChannel, connect to the Server Side through Server registered IP addrerss and Port number, the same as Server Side set the bolocking is false, open a Selector, register a OP_READ and OP_WRITE Event to this selector, the came to the loop circle, listen-in the OP_READ and _OP_WRITE Event, while the registered event happened, retrieved the info from the channel and handle the Event, if it's isReadable, output it from console, in other, send the data to Server Side through the SocketChannel;

The Server Side Source Code

public class TestEchoServer {
	
	private static final Logger logger = Logger.getLogger(TestEchoServer.class);
	
	private Selector selector = null;
	
	private ServerSocketChannel serverSocketChannel = null;
	
	private int port = 8000;
	
	private Charset charset=Charset.forName("UTF-8");

	public TestEchoServer()throws IOException{
		selector = Selector.open();
		serverSocketChannel= ServerSocketChannel.open();
		serverSocketChannel.socket().setReuseAddress(true);
		serverSocketChannel.configureBlocking(false);
		serverSocketChannel.socket().bind(new InetSocketAddress(port));
		logger.info("Server is start[" + new InetSocketAddress(port).getAddress() + ":" + port + "]");
	}

	public void service() throws IOException{
		
		logger.info("ServerSocketChannel register [" + SelectionKey.OP_ACCEPT + "] to selector");
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT );
		while (selector.select() > 0) {
//			logger.debug("Select.select() value: " + selector.select());
			Set readyKeys = selector.selectedKeys();
			Iterator it = readyKeys.iterator();
			while (it.hasNext()) {
				SelectionKey key = null;
				try {
					key = (SelectionKey) it.next();
					it.remove();

					if (key.isAcceptable()) {
						logger.info("Selection Key isAcceptable: " + key.isAcceptable());
						ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
						SocketChannel socketChannel = (SocketChannel) ssc.accept();
						logger.info("Recieved Client Connection:" + socketChannel.socket().getInetAddress() + ":" + socketChannel.socket().getPort());
						socketChannel.configureBlocking(false);
						
						ByteBuffer buffer = ByteBuffer.allocate(1024);
						socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, buffer);
						logger.info("SocketChannel register [" + SelectionKey.OP_READ  + "] and [" + SelectionKey.OP_WRITE + "] to selector");
					}
					
					if (key.isReadable()) {
						logger.info("Selection Key isReadable");
						receive(key);
					}
					
					if (key.isWritable()) {
//						logger.info("Selection Key isWritable");
						send(key);
					}
				} catch (IOException e) {
					e.printStackTrace();
					try {
						if (key != null) {
							key.cancel();
							key.channel().close();
						}
					} catch (Exception ex) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	public void send(SelectionKey key) throws IOException {
//		logger.info("send");
		ByteBuffer buffer = (ByteBuffer) key.attachment();
		SocketChannel socketChannel = (SocketChannel) key.channel();
		buffer.flip(); 
		String data = decode(buffer);
		if (data.indexOf("\r\n") == -1){
			return;
		}
		String outputData = data.substring(0, data.indexOf("\n") + 1);
		logger.info("outputData: " + outputData);
		ByteBuffer outputBuffer = encode("echo:" + outputData);
		while (outputBuffer.hasRemaining()){
			socketChannel.write(outputBuffer);
		}

		ByteBuffer temp = encode(outputData);
		buffer.position(temp.limit());
		buffer.compact();

		if (outputData.equals("bye\r\n")) {
			key.cancel();
			socketChannel.close();
			logger.info("Close Client Connection");
		}
	}

	public void receive(SelectionKey key) throws IOException {
		
		logger.info("receive");
		
		ByteBuffer buffer = (ByteBuffer) key.attachment();

		SocketChannel socketChannel = (SocketChannel) key.channel();
		ByteBuffer readBuff = ByteBuffer.allocate(32 * 1024);
		socketChannel.read(readBuff);
		readBuff.flip();

		buffer.limit(buffer.capacity());
		buffer.put(readBuff);
		logger.info("Recieved data: " + decode(buffer));
	}

	public String decode(ByteBuffer buffer) { 
		CharBuffer charBuffer = charset.decode(buffer);
		return charBuffer.toString();
	}

	public ByteBuffer encode(String str) { 
		return charset.encode(str);
	}

	public static void main(String args[]) throws Exception {
		TestEchoServer server = new TestEchoServer();
		server.service();
	}
}

 

The Client Side Source Code:

public class TestEchoClient {

	private SocketChannel socketChannel = null;
	
	private ByteBuffer sendBuffer = ByteBuffer.allocate(32 * 1024);
	
	private ByteBuffer receiveBuffer = ByteBuffer.allocate(32 * 1024);
	
	private Charset charset = Charset.forName("UTF-8");
	
	private Selector selector;
	
	private boolean isSend = false;
	
	public TestEchoClient() throws IOException {
		socketChannel = SocketChannel.open();
		InetAddress ia = InetAddress.getLocalHost();
		InetSocketAddress isa = new InetSocketAddress(ia, 8000);
		socketChannel.connect(isa);
		socketChannel.configureBlocking(false);
		log("Client: connection establish[" + isa.getHostName() + ":" + isa.getPort() + "]", false);
		selector = Selector.open();
	}

	public static void main(String args[]) throws IOException {
		final TestEchoClient client = new TestEchoClient();
		Thread receiver = new Thread() {
			public void run() {
				client.receiveFromUser();
			}
		};

		receiver.start();
		client.talk();
	}

	public void receiveFromUser() {
		try {
			BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
			String msg = null;
			while ((msg = localReader.readLine()) != null) {
				log("Read From System Console: " + msg, false);
				isSend = true;
				log("Command line thread set isSend: " + isSend, false);
				synchronized (sendBuffer) {
					sendBuffer.put(encode(msg + "\r\n"));
				}
				if (msg.equals("bye")){
					log("Client Exit", false);
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void talk() throws IOException {
		log("SocketChannel register [" + SelectionKey.OP_READ  + "] and [" + SelectionKey.OP_WRITE + "] to selector", false);
		socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
		while (selector.select() > 0) {
			Set readyKeys = selector.selectedKeys();
			Iterator it = readyKeys.iterator();
			while (it.hasNext()) {
				SelectionKey key = null;
				try {
					key = (SelectionKey) it.next();
					it.remove();

					if (key.isReadable()) {
						receive(key);
					}
					if (key.isWritable()) {
						send(key);
					}
				} catch (IOException e) {
					e.printStackTrace();
					try {
						if (key != null) {
							key.cancel();
							key.channel().close();
						}
					} catch (Exception ex) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	public void send(SelectionKey key) throws IOException {
		if(!isSend) {
			return;
		}
		SocketChannel socketChannel = (SocketChannel) key.channel();
		synchronized (sendBuffer) {
			sendBuffer.flip(); 
			socketChannel.write(sendBuffer);
			sendBuffer.compact();
		}
		isSend = false;
		log("Send method set isSend: " + isSend, false );
	}

	public void receive(SelectionKey key) throws IOException {
		SocketChannel socketChannel = (SocketChannel) key.channel();
		socketChannel.read(receiveBuffer);
		receiveBuffer.flip();
		String receiveData = decode(receiveBuffer);

		if (receiveData.indexOf("\n") == -1){
			return;
		}

		String outputData = receiveData.substring(0, receiveData.indexOf("\n") + 1);
		log("Recieve Data: " + outputData, false);
		if (outputData.equals("echo:bye\r\n")) {
			key.cancel();
			socketChannel.close();
			System.out.println("Exit");
			selector.close();
			System.exit(0);
		}

		ByteBuffer temp = encode(outputData);
		receiveBuffer.position(temp.limit());
		receiveBuffer.compact();
	}

	public String decode(ByteBuffer buffer) {
		CharBuffer charBuffer = charset.decode(buffer);
		return charBuffer.toString();
	}

	public ByteBuffer encode(String str) { 
		return charset.encode(str);
	}
	
	public void log(String msg, boolean err) {
		String type = err ? "[WARN]" : "[INFO]";
		msg = new Date() + " --> " + type + " " + msg;
		System.out.println(msg);
	}
}

 

 

  • 大小: 26.5 KB
  • 大小: 18.3 KB
0
0
分享到:
评论

相关推荐

    JAVA-NIO-DEMO

    本示例"JAVA-NIO-DEMO"提供了关于Java NIO的实际应用,通过Anontion(注解)、Applet(小程序)和NIO的Demo,帮助开发者更深入地理解和掌握这些概念。 首先,让我们深入了解Java NIO。NIO的核心组件包括: 1. **...

    基于java NIO的socket通信demo

    在这个“基于java NIO的socket通信demo”中,我们将探讨如何使用NIO进行服务器和客户端的Socket通信,并解决通信过程中的字符集乱码问题。 首先,我们来看`NioServer.java`。这个文件中包含了一个基于NIO的服务器端...

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    java nio demo

    会有一点需要修改,比如jar包的支持,详情请见http://blog.csdn.net/lingchen_yu,blog名字叫《java nio demo简单nio项目》,如果或者自己修改jar包支持,建议先看一下,因为没写神马注释

    JavaNIO chm帮助文档

    Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...

    java NIO.zip

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统的I/O模型的新技术。自Java 1.4版本引入NIO后,它为Java开发者提供了更高效的数据传输方式,尤其是在处理大量并发...

    Java NIO英文高清原版

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准I/O(BIO)模型的一种新机制。NIO在Java 1.4版本引入,提供了更高效的数据处理和通道通信方式,特别适用于高并发、大数据...

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    java-NIO-demo

    Java NIO(Non-blocking Input/Output)是一种在Java中处理I/O操作的新方式,相比于传统的BIO( Blocking I/O),NIO提供了更高效的数据传输能力,尤其在处理大量并发连接时。NIO的核心概念包括通道(Channels)、...

    java nio 包读取超大数据文件

    ### Java NIO 处理超大数据文件的知识点详解 #### 一、Java NIO简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...

    java nio demo wing版

    nio超简单的小demo的swing版,详情请见http://blog.csdn.net/lingchen_yu,blog名字叫《java nio demo简单nio项目》,建议先看一下,因为没写神马注释

    java nio proraming pdf

    java.nio (NIO stands for non-blocking I/O) is a collection of Java programming language APIs that offer features for intensive I/O operations. It was introduced with the J2SE 1.4 release of Java by ...

    java NIO技巧及原理

    Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...

    java.nio demo

    Java的IO操作集中在java.io这个包中,是基于流的同步(blocking)API。对于大多数应用来说,这样的API使用很方便,然而,一些对性能要求较高的应用,尤其是服务端应用,往往需要一个更为有效的方式来处理IO。从JDK ...

    bio nio aio demo

    在Java世界中,I/O(输入/输出)是任何应用程序不可或缺的部分。为了处理与外部世界的交互,Java提供了三种不同的I/O模型:BIO( Blocking I/O...这个"bio nio aio demo"项目是学习和比较Java I/O模型的一个宝贵实践。

    java NIO实例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输方式。传统的Java I/O模型(BIO)在处理大量并发连接时效率较...

    java socket Bio Nio example

    在Java中,Socket主要分为两种模式:BIO(Blocking I/O)和NIO(Non-blocking I/O)。这两个模式分别有不同的应用场景和优缺点。 **一、Java Socket BIO** BIO,即阻塞I/O模型,是Java最初提供的网络通信方式。在...

Global site tag (gtag.js) - Google Analytics