JAVA socket编程之NIO技术_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > JAVA socket编程之NIO技术

JAVA socket编程之NIO技术

 2014/5/18 13:20:18  247687009  程序员俱乐部  我要评论(0)
  • 摘要:JavaNIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内容,如果没有内容进来,read()也是傻傻的等,这会影响我们程序继续做其他事情,那么改进做法就是开设线程,让线程去等待,但是这样做也是相当耗费资源的。JavaNIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样
  • 标签:Java 编程 技术 socket
Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内容,如果没有内容进来,read()也是傻傻的等,这会影响我们程序继续做其他事情,那么改进做法就是开设线程,让线程去等待,但是这样做也是相当耗费资源的。
Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了。
Java NIO出现不只是一个技术性能的提高,你会发现网络上到处在介绍它,因为它具有里程碑意义,从JDK1.4开始,Java开始提高性能相关的功能,从而使得Java在底层或者并行分布式计算等操作上已经可以和C或Perl等语言并驾齐驱。
简单说:使用java nio开发网络通讯 是比较快速和方面的。因为他可以不用阻塞的方式侦听客户端的连接 ,在java nio中可以使用基于事件的机制进行非阻塞通讯,当有新的事
件进行注册时 我们只需要通过事件侦听机制 获取新的事件
简单的说就是 java nio中里面有一个selector  异步 I/O 中的核心对象名为 Selector。Selector 就是您注册对各种 I/O 事件的兴趣的地方。
下面上代码,注释说明


class="java">
package nio.socket;

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;

import org.junit.Test;

public class Server {

	@Test
	public void server() throws IOException {
		//selector就是您注册对各种io事件的兴趣的地方 而且当那些事件发生时 就是这个对象告诉您所发生的事情
		Selector selector = Selector.open();
		//开启一个ServerSocketChannel通道
		ServerSocketChannel ssc = ServerSocketChannel.open();
		//绑定地址和端口
		ssc.bind(new InetSocketAddress("localhost", 8080));
		// 设置为非阻塞式的IO 
		ssc.configureBlocking(false);
		//注册感兴趣的
		ssc.register(selector, SelectionKey.OP_ACCEPT);
		//设置一个缓冲
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		//接收客户端过来的通道
		SocketChannel sc = null;
		while (true) {
			selector.select();  //查询事件,监听一旦有我们注册的感兴趣的事件发生的时候便会激活
			Set<SelectionKey> selectedKeys = selector.selectedKeys(); //获取到触发的事件集合
			SelectionKey key = null;
			Iterator<SelectionKey> iterator = selectedKeys.iterator();
			for (;iterator.hasNext();) {//循环
				key = iterator.next();
				if(key.isAcceptable()){ //表示触发的事件是新连接
					ServerSocketChannel newssc = (ServerSocketChannel) key.channel();
					 sc = newssc.accept(); //获取到客户端过来的通道
					 sc.configureBlocking(false); //设置为非阻塞式IO
					 sc.register(selector, SelectionKey.OP_READ);//注册读取事件
					 iterator.remove(); //事件集合中删除
					 System.out.println("有新的连接");
				}else if(key.isReadable()){ //表示读取事件 在连接时候注册了读取事件 在这里处理
					sc = (SocketChannel) key.channel(); //得到客户端的通道
					while(true){
						buffer.clear(); //如果信息量超过预设的缓存就会便会批量读取 重复使用 这里必须清理一下
						int read = sc.read(buffer);
						if(read == -1 || read == 0)break; //如果读取完了 则退出循环
						if(read > 0){
							byte[] array = buffer.array();
							System.out.println("接受到的数据"+new String(array));
						}
					}
					buffer.clear();
					buffer.put("这是我的测试".getBytes());
					buffer.flip();//flip方法将Buffer从写模式切换到读模式
					sc.write(buffer);
					sc.close();//使用完毕关闭客户端的通道
					System.out.println("操作结束==============");
					iterator.remove();
				}
				
			}
		}

	}

}

发表评论
用户名: 匿名