`
kylinsoong
  • 浏览: 235656 次
  • 性别: 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

    Anontion、Applet、NIO等Demo,可以辅助理解一下相关知识点

    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的socket通信demo

    java NIO 创建的服务端,能够异步响应客户端的请求,客户端采用nio异步请求服务端,通信之间的乱码使用charset解决

    Java NIO英文高清原版

    Java NIO英文高清原版

    java NIO 中文版

    讲解了 JavaIO 与 JAVA NIO区别,JAVA NIO设计理念,以及JDK中java NIO中语法的使用

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

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

    java nio 实现socket

    java nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socket

    java nio 包读取超大数据文件

    Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据...

    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 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 英文文字版

    Because the NIO APIs supplement the I/O features of version 1.3, rather than replace them, you'll also learn when to use new APIs and when the older 1.3 I/O APIs are better suited to your particular ...

    java.nio demo

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

    java nio中文版

    java NIO是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持...

    java nio 通信服务器、客户端完整例子

    用java编写的nio通信的例子,nio是io编程的新版本,比io较流行。同时本例子是适用socket通信的。可以在此基础上,添加您的个人应用。本例子适用于:java通信的学习者,android平台通信的学习者。

    Java Nio selector例程

    java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...

    基于netty的nio使用demo源码

    基于netty的nio使用demo源码

    java socket Bio Nio example

    几个用java写的小程序,实现了bio和nio

Global site tag (gtag.js) - Google Analytics