public class NioServer {
// 通道选择器,监控多个Channel并决定哪些channel能进行读或写,一个selector管理多个channel
private Selector selector;
public NioServer init(int port) throws IOException{
// 创建一个ServerSocket通道
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.socket().bind(new InetSocketAddress(port));
// 获取通道选择器
selector=Selector.open();
// 将通道管理器与通道绑定,并为该通道注册SelectionKey.OP_ACCEPT事件
// 只有当该事件到达时,Selector.select()会返回,否则一直阻塞。
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
return this;
}
public void listen() throws IOException{
System.out.println("服务器端启动成功");
// 使用轮询访问selector
while(true){
// 当有注册的事件到达时方法返回,否则阻塞。
selector.select();
// 获取selector中的迭代器,选中项为注册的事件
Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
while(ite.hasNext()){
SelectionKey key = iter.next();
// 删除已选key,防止重复处理
iter.remove();
// 客户端请求连接事件
if(key.isAcceptable()){
ServerSocketChannel server = (ServerSocketChannel)key.channel();
// 获得客户端连接通道
SocketChannel channel = server.accept();
channel.configureBlocking(false);
// 向客户端发消息
channel.write(ByteBuffer.wrap(new String("send message to client").getBytes()));
// 与客户端连接成功后,为客户端通道注册SelectionKey.OP_READ事件
channel.register(selector, SelectionKey.OP_READ);
System.out.println("客户端请求连接事件");
}else if(key.isReadable()){ // 有可读数据事件
// 获取客户端传输数据可读取消息通道。
SocketChannel channel = (SocketChannel)key.channel();
// 创建读取数据缓冲器
ByteBuffer buffer = ByteBuffer.allocate(10);
int read = channel.read(buffer);
byte[] data = buffer.array();
String message = new String(data);
System.out.println("receive message from client, size:" + buffer.position() + " msg: " + message);
// ByteBuffer outbuffer = ByteBuffer.wrap(("server.".concat(msg)).getBytes());
// channel.write(outbuffer);
}
}
}
}
public static void main(String[] args) throws IOException {
new NioServer().init(9981).listen();
}
}
public class NioClient {
private Selector selector;
public NioClient init(String serverIp, int port) throws IOException{
// 获取socket通道
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
// 获得通道管理器
selector=Selector.open();
// 客户端连接服务器,需要调用channel.finishConnect();才能实际完成连接。
channel.connect(new InetSocketAddress(serverIp, port));
// 为该通道注册SelectionKey.OP_CONNECT事件
channel.register(selector, SelectionKey.OP_CONNECT);
return this;
}
public void listen() throws IOException{
System.out.println("客户端启动");
// 轮询访问selector
while(true){
// 选择注册过的io操作的事件(第一次为SelectionKey.OP_CONNECT)
selector.select();
Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
while(iter.hasNext()){
SelectionKey key = iter.next();
// 删除已选的key,防止重复处理
ite.remove();
if(key.isConnectable()){
SocketChannel channel=(SocketChannel)key.channel();
// 如果正在连接,则完成连接
if(channel.isConnectionPending()){
channel.finishConnect();
}
channel.configureBlocking(false);
// 向服务器发送消息
channel.write(ByteBuffer.wrap(new String("send message to server.").getBytes()));
// 连接成功后,注册接收服务器消息的事件
channel.register(selector, SelectionKey.OP_READ);
System.out.println("客户端连接成功");
}else if(key.isReadable()){ // 有可读数据事件。
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer = ByteBuffer.allocate(10);
channel.read(buffer);
byte[] data = buffer.array();
String message = new String(data);
System.out.println("recevie message from server:, size:" + buffer.position() + " msg: " + message);
// ByteBuffer outbuffer = ByteBuffer.wrap(("client.".concat(msg)).getBytes());
// channel.write(outbuffer);
}
}
}
}
public static void main(String[] args) throws IOException {
new NioClient().init("127.0.0.1", 9981).listen();
}
}