通過SocketChannel 和 ServerSocketChannel 寫一個(gè)阻塞的網(wǎng)絡(luò)IO操作
package edu.xcdq;
/**
* @qvthor liuwenzheng
* @date 2021/5/18 20:50
*/
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 De {
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);
// 進(jìn)行服務(wù)的綁定
serverSocket.bind(address);
// 注冊(cè)到selector百拓,等待連接
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服務(wù)器運(yùn)行布持,端口:" + 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)前的時(shí)間為:" + new Date()).getBytes());
byteBuffer.flip();
// 輸出內(nèi)容
client.write(byteBuffer);
client.register(selector, SelectionKey.OP_READ);
}
}
}
客戶端
package edu.xcdq;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
/**
* @qvthor liuwenzheng
* @date 2021/5/18 16:16
*/
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);
//進(jìn)行服務(wù)器綁定
serverSocket.bind(address);
//注冊(cè)到selector,等待鏈接
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服務(wù)器運(yùn)行喂急,端口:"+port);
//數(shù)據(jù)緩沖區(qū)
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (true){
if (selector.select()>0){
//選擇一組鍵,并且相應(yīng)的通道已經(jīng)準(zhǔn)備就緒
//去除全部生成的key
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iter = selectionKeys.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
selectionKeys.clear();;
}
}
}
public static void writable(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException {
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)前的時(shí)間為:" + new Date()).getBytes());
byteBuffer.flip();
// 輸出內(nèi)容
client.write(byteBuffer);
client.register(selector, SelectionKey.OP_READ);
}
}