服務(wù)器
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
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 SelectorServiceDemo {
public static void main(String[] args) throws Exception {
int port = 8000;
// 通過open()方法找到Selector
Selector selector = Selector.open();
// 打開服務(wù)器的通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 服務(wù)器配置為非阻塞
serverSocketChannel.configureBlocking(false);
ServerSocket serverSocket = serverSocketChannel.socket();
InetSocketAddress address = new InetSocketAddress(port);
// 進行服務(wù)的綁定
serverSocket.bind(address);
// 注冊到selector郊供,等待連接
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服務(wù)器運行,端口:" + port);
// 數(shù)據(jù)緩沖區(qū)
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (true) {
if ((selector.select()) > 0) {
// 選擇一組鍵,并且相應(yīng)的通道已經(jīng)準(zhǔn)備就緒
// 取出全部生成的key
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iter = selectedKeys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
if (key.isAcceptable()) {
acceptable(key, byteBuffer, selector);
} else if (key.isReadable() && key.isValid()) {
readable(selector, byteBuffer, key);
} else if (key.isWritable() && key.isValid()) {
writable(selector, byteBuffer, key);
}
}
// 清除全部的key
selectedKeys.clear();
}
}
}
public static void writable(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
byteBuffer.clear();
// 向緩沖區(qū)中設(shè)置內(nèi)容
byteBuffer.put(("歡迎學(xué)習(xí)NIO教程").getBytes());
byteBuffer.flip();
// 輸出內(nèi)容
client.write(byteBuffer);
client.register(selector, SelectionKey.OP_READ);
}
public static void readable(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
byteBuffer.clear();
// 讀取內(nèi)容到緩沖區(qū)中
int readSize = client.read(byteBuffer);
if (readSize > 0) {
System.out.println("服務(wù)器端接受客戶端數(shù)據(jù):" + new String(byteBuffer.array(), 0, readSize));
client.register(selector, SelectionKey.OP_WRITE);
}
}
public static void acceptable(SelectionKey key, ByteBuffer byteBuffer, Selector selector) throws IOException {
ServerSocketChannel server = (ServerSocketChannel) key.channel();
// 接收新連接 和BIO寫法類是都是accept
SocketChannel client = server.accept();
// 配置為非阻塞
client.configureBlocking(false);
byteBuffer.clear();
// 向緩沖區(qū)中設(shè)置內(nèi)容
byteBuffer.put(("當(dāng)前的時間為:" + new Date()).getBytes());
byteBuffer.flip();
// 輸出內(nèi)容
client.write(byteBuffer);
client.register(selector, SelectionKey.OP_READ);
}
}
結(jié)果
![圖一.png](https://upload-images.jianshu.io/upload_images/25693962-5ca5a931b4852ff5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
客戶端
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
public class SelectorClientDemo {
public static void main(String[] args) throws Exception {
// 打開socket通道
SocketChannel socketChannel = SocketChannel.open();
// 設(shè)置為非阻塞方式
socketChannel.configureBlocking(false);
// 通過open()方法找到
Selector selector = Selector.open();
// 注冊連接服務(wù)端socket動作
socketChannel.register(selector, SelectionKey.OP_CONNECT);
// 連接
socketChannel.connect(new InetSocketAddress("127.0.0.1", 8000));
/* 數(shù)據(jù)緩沖區(qū) */
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (true) {
if ((selector.select()) > 0) {
// 選擇一組鍵在辆,并且相應(yīng)的通道已經(jīng)準(zhǔn)備就緒
Set<SelectionKey> selectedKeys = selector.selectedKeys();// 取出全部生成的key
Iterator<SelectionKey> iter = selectedKeys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next(); // 取出每一個key
if (key.isConnectable()) {
connection(selector, byteBuffer, key);
} else if (key.isReadable() && key.isValid()) {
readable(selector, byteBuffer, key);
} else if (key.isWritable() && key.isValid()) {
writable(selector, byteBuffer, key);
}
}
selectedKeys.clear(); // 清楚全部的key
}
}
}
public static void writable(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
byteBuffer.clear();
// 向緩沖區(qū)中設(shè)置內(nèi)容
byteBuffer.put(("學(xué)習(xí)NIO!").getBytes());
byteBuffer.flip();
// 輸出內(nèi)容
client.write(byteBuffer);
client.register(selector, SelectionKey.OP_READ);
}
public static void readable(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
byteBuffer.clear();
// 讀取內(nèi)容到緩沖區(qū)中
int readSize = client.read(byteBuffer);
if (readSize > 0) {
System.out.println("客戶端接受服務(wù)器端數(shù)據(jù):" + new String(byteBuffer.array(), 0, readSize));
client.register(selector, SelectionKey.OP_WRITE);
}
}
public static void connection(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
if (client.isConnectionPending()) {
client.finishConnect();
byteBuffer.clear();
// 向緩沖區(qū)中設(shè)置內(nèi)容
byteBuffer.put(("isConnect,當(dāng)前的時間為:" + new Date()).getBytes());
byteBuffer.flip();
// 輸出內(nèi)容
client.write(byteBuffer);
}
client.register(selector, SelectionKey.OP_READ);
}
}
結(jié)果