java 使用Selector获取无阻塞的网络服务
———–Selector获取无阻塞的网络服务:
使用Selector可以构建一个非阻塞的网络服务;
在新IO中实现网络程序需要依靠ServerSocketChannel类与SocketChannel lei ;
// 可选通道多路器:
public abstract class Selector
extends Object
A multiplexor of SelectableChannel objects.
A selector may be created by invoking the open method of this class, which will use the system’s default selector provider to create a new selector. A selector may also be created by invoking the openSelector method of a custom selector provider. A selector remains open until it is closed via its close method.
// 服务器Socket通道:
public abstract class ServerSocketChannel
extends AbstractSelectableChannel
// 基于流的监听Socket连接的可选择通道
A selectable channel for stream-oriented listening sockets.
// Socket通道:
public abstract class SocketChannel
extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel
// 基于流的连接socket连接的可选择通道
A selectable channel for stream-oriented connecting sockets.
——–实现非阻塞服务器端:
package com.mldn;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.SelectionKey;
import java.nio.ByteBuffer;
import java.net.ServerSocket;
import java.net.InetSocketAddress;
import java.util.Date;
import java.util.Set;
import java.util.Iterator;
/*
将创建一个非阻塞的服务器端,该服务器不能自动关闭!
*/
public class SelectorServer
{
public static void main(String[] args) throws Exception
{
int[] ports = {8000, 8001, 8002, 8003, 8005, 8006}; // 5个监听端口
Selector selector = Selector.open(); // 打开一个选择器
for (int x = 0; x < ports.length; x++)
{
ServerSocketChannel serverSocChanl = null; // 声明服务器socket通道
serverSocChanl = ServerSocketChannel.open(); // 打开此通道
serverSocChanl.configureBlocking(false); // 当前服务器通道配置为非阻塞
ServerSocket serverSoc = serverSocChanl.socket(); // 获取服务器Socket
InetSocketAddress socAddress = null; // 声明socket地址
socAddress = new InetSocketAddress(ports[x]); // 实例化绑定地址
serverSoc.bind(socAddress); // 绑定socket服务器与此地址,每个服务器socket对应一个socket地址
// 将当前服务器通道注册到当前选择器,并设置为监听操作
serverSocChanl.register(selector, SelectionKey.OP_ACCEPT);
System.out.println(“服务器运行,在” + ports[x] + “端口监听。”);
}
// 获取生成的全部key,并通过连接进行判断是否获取客户端的输出
int keysAdd = 0;
while ((keysAdd = selector.select()) > 0) //选择当前所有key,其对应的通道已经生成
{
Set
Iterator
while (iter.hasNext())
{
SelectionKey key = iter.next(); // 取出每一个key
if (key.isAcceptable()) // 此key对应的通道是等待连接的socket
{
ServerSocketChannel server = (ServerSocketChannel)key.channel(); // 创建当前key对应的服务器Socket通道
SocketChannel socChanl = server.accept(); // 接收新连接
socChanl.configureBlocking(false); // 配置当前socket通道是非阻塞的
ByteBuffer outBuf = ByteBuffer.allocateDirect(1024);
outBuf.put((“你好!当前时间为: ” + new Date()).getBytes()); // 写入内容到缓冲区
outBuf.flip(); // 重置position=0,limit有效内容;
socChanl.write(outBuf); // 从缓冲区写入socket通道
socChanl.close(); // 关闭当前通道,可以自定义关闭的条件比如由客户端决定
}
}
selectedKeys.clear(); // 清除所有key,以便下次循环重新加载被选择的通道对应的key
}
}
}
声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 嗅谱网
转载请注明:转自《java 使用Selector获取无阻塞的网络服务》
本文地址:http://www.xiupu.net/archives-179.html
关注公众号:
微信赞赏
支付宝赞赏