?服務器端:
?
?
// 1. 分配一個 ServerSocketChannel 文件描述符
serverChannel = ServerSocketChannel.open();
// 2. 從 ServerSocketChannel里獲取一個對于的 socket
serverSocket = serverChannel.socket();
// 3. 生成一個 Selector
selector = Selector.open();
// 4. 把 socket 綁定到端口上
serverSocket.bind(new InetSocketAddress(iport));
// 5. serverChannel 未非bolck
serverChannel.configureBlocking(false);
// 6. 通過Selector注冊ServerSocketChannel: 只能注冊 accept
// 而SocketChannel可以注冊CONNENCT,READ,WRITE ; register -> validOps
// 在各個子類實現不同
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
try {
// 獲得IO準備就緒的channel數量
int n = selector.select();
// 沒有channel準備就緒,繼續執行
if (n == 0) {
continue;
}
// 用一個iterator返回Selector的selectedkeys
Iterator it = selector.selectedKeys().iterator();
// 處理每一個SelectionKey
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
// 判斷是否有新的連接到達
if (key.isAcceptable()) {
// 返回SelectionKey的ServerSocketChannel
ServerSocketChannel server = (ServerSocketChannel) key
.channel();
System.out.println("有連接");
SocketChannel channel = server.accept();
registerChannel(selector, channel, SelectionKey.OP_READ);
doWork(channel);
}
// 判斷是否有數據在此channel里需要讀取
if (key.isReadable()) {
processData(key);
}
}
// 刪除 selectedkeys
it.remove();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
?
?
?
?客戶端:
?
?
//打開socket通道
SocketChannel socketChannel = SocketChannel.open();
//設置非阻塞方式
socketChannel.configureBlocking(false);
//打開選擇器
Selector selector = Selector.open();
//注冊連接到服務器socket動作
socketChannel.register(selector, SelectionKey.OP_CONNECT);
//連接
socketChannel.connect( new InetSocketAddress("localhost",9988));
Set<SelectionKey> selectkeySets;
SelectionKey selectionKey;
Iterator<SelectionKey> iterator;
//與服務器通信通道
SocketChannel clientChannel ;
while(true){
//選擇一組建,其相應的通道已為I/O操作準備就緒
//此方法執行處于阻塞模式的選擇操作
selector.select(TIME_OUT);
//返回此選擇器的已選擇鍵集。
selectkeySets = selector.selectedKeys();
iterator = selectkeySets.iterator();
while(iterator.hasNext()){
selectionKey = iterator.next();
if (selectionKey.isConnectable()) {
clientChannel = (SocketChannel)selectionKey.channel();
// 判斷此通道上是否正在進行連接操作。
// 完成套接字通道的連接過程。
if (clientChannel.isConnectionPending()) {//判斷此通道上是否正在進行連接操作
clientChannel.finishConnect(); //完成套接字通道的連接過程
}
clientChannel.register(selector, SelectionKey.OP_WRITE);
}else if (selectionKey.isReadable()) {
clientChannel = (SocketChannel)selectionKey.channel();
//將緩沖區清空
receiveBuffer.clear();
//讀取服務器發送來的數據庫到緩沖區
count = clientChannel.read(receiveBuffer);//count 讀取到的字節數
if (count > 0) {
clientChannel.register(selector, SelectionKey.OP_WRITE);
}
}else if (selectionKey.isWritable()) {
sendBuffer.clear();
clientChannel = (SocketChannel)selectionKey.channel();
clientChannel.write(sendBuffer);
System.out.println("客戶端向服務器發送數據:"+sendText);
clientChannel.register(selector, SelectionKey.OP_READ);
}
}
}
?
已有 0 人發表留言,猛擊->>這里<<-參與討論
ITeye推薦