public class NIOServer {
// 通道管理器(Selector)
private static Selector selector;
public static void main(String[] args) throws IOException {
// 創建通道管理器(Selector)
selector = Selector.open();
// 創建通道ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 將通道設置爲非阻塞
serverSocketChannel.configureBlocking(false);
// 將ServerSocketChannel對應的ServerSocket綁定到指定端口(port)
ServerSocket serverSocket = serverSocketChannel.socket();
serverSocket.bind(new InetSocketAddress(8989));
/**
* 將通道(Channel)註冊到通道管理器(Selector),併爲該通道註冊selectionKey.OP_ACCEPT事件
* 註冊該事件後,當事件到達的時候,selector.select()會返回,
* 如果事件沒有到達selector.select()會一直阻塞。
*/
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
// 循環處理
while (true) {
try{
// 當註冊事件到達時,方法返回,否則該方法會一直阻塞
selector.select();
// 獲取監聽事件
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
// 迭代處理
while (iterator.hasNext()) {
// 獲取事件
SelectionKey key = iterator.next();
// 客戶端請求連接事件,接受客戶端連接就緒
if (key.isAcceptable()) {
acceptHandler(key);
} else if (key.isReadable()) {// 監聽到讀事件,對讀事件進行處理
readHandler(key);
}
// 移除事件,避免重複處理
iterator.remove();
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 處理客戶端連接成功事件
*/
private static void acceptHandler(SelectionKey key) throws IOException {
// 獲取客戶端連接通道
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = server.accept();
socketChannel.configureBlocking(false); // 設置非阻塞
// 信息通過通道發送給客戶端
socketChannel.write(ByteBuffer.wrap(new String("hello client , 撲街!!").getBytes()));
// 給通道設置讀事件,客戶端監聽到讀事件後,進行讀取操作
socketChannel.register(selector, SelectionKey.OP_READ);
}
/**
* 監聽到讀事件,讀取客戶端發送過來的消息
*/
private static void readHandler(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int count ;
buffer.clear();
try {
while ((count = channel.read(buffer)) > 0) {
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
System.out.println("讀取客戶端消息: " + new String(bytes));
}
if (count < 0) {
channel.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class NIOClient {
public static void main(String[] args) throws IOException, InterruptedException {
// 創建通道SocketChannel
SocketChannel channel = SocketChannel.open();
// 將通道設置爲非阻塞
channel.configureBlocking(false);
// 客戶端連接服務器,其實方法執行並沒有實現連接,
// 需要在handleConnect方法中調channel.finishConnect()才能完成連接
channel.connect(new InetSocketAddress("localhost", 8989));
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (!channel.finishConnect()) {
TimeUnit.SECONDS.sleep(2);
System.out.println("111111111111111111");
}
for (int i=0; i<5; i++) {
TimeUnit.MICROSECONDS.sleep(2);
String message = "send message " + i + " from" + "AAAAA";
buffer.put(message.getBytes());
buffer.flip();
//buffer先把數據讀入到buffer,然後channel先把buffer中的數據寫入到channel,
channel.write(buffer);
buffer.clear();
}
{{
ByteBuffer buffer2 = ByteBuffer.allocate(1024);
int count ;
buffer2.clear();
try {
while ((count = channel.read(buffer2)) > 0) {
buffer2.flip();
byte[] bytes = new byte[buffer2.remaining()];
buffer2.get(bytes);
System.out.println("讀取客戶端消息: " + new String(bytes));
}
} catch (IOException e) {
e.printStackTrace();
}
}}
channel.close();
}
}