一,本章目标
了解Selector类的作用
可以使用新IO构建异步非阻塞服务器
二,具体内容
之前在讲解Socket程序的时候,读者可以发现,所有的Socket程序在运行的时候,服务器必须始终等待着客户端的链接,那么此时就会造成大量的资源浪费,所以引入了非阻塞的IO操作,那么此时就可以通过Selector完成。
实际上,新IO中主要是解决服务器端的通讯性能。
具体例子如下:
package Selector类;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
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.Date;
import java.util.Iterator;
import java.util.Set;
public class Demo1 {
/**
* @param args
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
int ports[] ={8000,8001,8002,8003,8005,8006};//要监听的五个端口
Selector selector = Selector.open();//通过open方法找到Selector
for(int i=0;i<ports.length;i++){
ServerSocketChannel initSer = null;
initSer = ServerSocketChannel.open();//打开服务器通道
initSer.configureBlocking(false);//服务器配置为非阻塞
ServerSocket initSock = initSer.socket();
InetSocketAddress address = null;
address = new InetSocketAddress(ports[i]);//绑定地址
initSock.bind(address);//进行绑定服务
initSer.register(selector,SelectionKey.OP_ACCEPT);//等待连接
System.out.println("服务器运行,在" + ports[i] + "端口监听");
}
int keysAdd = 0;
while((keysAdd = selector.select())>0){//选择一组健,并且响应的通道已经准备好了
Set<SelectionKey> selectedKeys = selector.selectedKeys();//取得全部的健
Iterator<SelectionKey> iter = selectedKeys.iterator();
while(iter.hasNext()){
SelectionKey key = iter.next();
if(key.isAcceptable()){
ServerSocketChannel server = (ServerSocketChannel)key.channel();
SocketChannel client = server.accept();//接受新连接
client.configureBlocking(false);//配置为非阻塞
ByteBuffer outbuf = ByteBuffer.allocateDirect(1024);
outbuf.put(("当前时间为:" + new Date()).getBytes());
outbuf.flip();
client.write(outbuf);
client.close();
}
}
selectedKeys.clear();
}
}
}服务器完成之后可以像之前那样编写普通客户端代码。也可以使用telnet命令。此时就完成了一个异步的操作服务器。
三,总结
本章再在实际的开发中使用较少,但是对服务器性能的操作代码上使用较多。
本文介绍如何利用Java NIO中的Selector类构建异步非阻塞服务器,通过实例演示服务器如何同时监听多个端口并处理客户端连接请求。
731

被折叠的 条评论
为什么被折叠?



