Java NIO初試

來源:互聯網
上載者:User

標籤:

Java的NIO採用selector來輪循,還是不錯,小試牛刀,下附代碼

Server:

import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;public class NIOServer {private Selector selector;public void initServer(int port) throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 開啟伺服器通訊端通道serverSocketChannel.configureBlocking(false);// 設定為非阻塞模式serverSocketChannel.socket().bind(new InetSocketAddress(port));// 綁定連接埠this.selector = Selector.open();// 開啟選取器// 註冊事件,當事件到達,selector。select()會返回,如果沒有事件會一直阻塞serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);// 註冊選取器,接受用戶端串連}public void listen() throws IOException {System.out.println("伺服器啟動!開始輪詢監聽訊息");while (true) {int ready = this.selector.select();if (ready == 0) {continue;}Iterator items = this.selector.selectedKeys().iterator();while (items.hasNext()) {SelectionKey key = (SelectionKey) items.next();// 刪除已經選擇的key,防止重複處理items.remove();// 請求串連if (key.isAcceptable()) {ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();if (serverSocketChannel == null) {continue;}SocketChannel socketChannel = serverSocketChannel.accept();//每次接受新的串連請求會產生新的通道,socketChannel.configureBlocking(false);socketChannel.write(ByteBuffer.wrap(new String("你好,用戶端,串連已建立,可以開始通訊!").getBytes()));//串連成功,發訊息給用戶端System.out.println("串連已經建立");socketChannel.register(this.selector, SelectionKey.OP_READ);//準備好接收資料} else if (key.isReadable()) {this.read(key);}}}}public void read(SelectionKey key) throws IOException {SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer byteBuffer = ByteBuffer.allocate(100);socketChannel.read(byteBuffer);byte[] data = byteBuffer.array();String msg = new String(data).trim();if (msg.equals("[email protected]#$%")) {//收到關閉指令,發送確認關閉的指令給用戶端,結束自身通道ByteBuffer sendBuffer = ByteBuffer.wrap(new String("bye close").getBytes());while (sendBuffer.hasRemaining()) {socketChannel.write(sendBuffer);}socketChannel.close();System.out.println("已經關閉");} else {System.out.println("server Receive:" + msg);//伺服器收到任何訊息都會給用戶端發送"收到"socketChannel.write(ByteBuffer.wrap(new String("收到!").getBytes()));}}public static void main(String[] args) {NIOServer server = new NIOServer();try {server.initServer(1377);server.listen();} catch (IOException e) {e.printStackTrace();}}}

  Client:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.util.Iterator;public class NIOClient {private Selector selector;//初始化public void initClient(String ipAddress, int port) throws IOException {SocketChannel socketChannel = SocketChannel.open();//開啟通訊端通道socketChannel.configureBlocking(false);//非阻塞this.selector = Selector.open();//開啟選取器socketChannel.connect(new InetSocketAddress(ipAddress, port));//指定ip地址和連接埠號碼用於串連socketChannel.register(this.selector, SelectionKey.OP_CONNECT);//通道註冊到選取器中,用於串連}//監聽public void listen() throws IOException {while (true) {//當用戶端關閉的時候需要結束輪循的動作,這樣程式才會結束if (!this.selector.isOpen()) {return;}int ready = this.selector.select();//這個才是真正的輪循啦,得到通道if (ready == 0) {continue;//如果selector中沒有SocketChannel,直接開始下一次咯 }Iterator items = this.selector.selectedKeys().iterator();while (items.hasNext()) {SelectionKey key = (SelectionKey) items.next();items.remove();//防止重複處理if (key.isConnectable()) {//串連System.out.println("正在串連,串連成功後,伺服器會返回結果!");SocketChannel socketChannel = (SocketChannel) key.channel();// 如果正在串連,則完成串連if (socketChannel.isConnectionPending()) {socketChannel.finishConnect();}socketChannel.register(this.selector, SelectionKey.OP_READ);//重新註冊該通道,用於讀取資料} else if (key.isReadable()) {//讀取this.read(key);}}}}/****************************************************//* * 用戶端關閉思路 * 用戶端伺服器 *  * 使用者輸入bye,需要關閉用戶端 *  * "[email protected]#$%"->"[email protected]#$%"                               約定好的內容("[email protected]#$%") *  * "bye close"<-"bye close"     ----->伺服器通道關閉        約定好的內容("bye close") *  * 用戶端通道關閉伺服器還可以接受別的請求 *  */public void read(SelectionKey key) throws IOException {SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer receiveBuffer = ByteBuffer.allocate(100);socketChannel.read(receiveBuffer);byte[] data = receiveBuffer.array();String msg = new String(data).trim();if (msg.equals("bye close")) {//用戶端和伺服器約定關閉,收到伺服器響應後可以關閉System.out.println("關閉");socketChannel.close();this.selector.close();return;}System.out.println("client receive:" + msg);BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String readMsg = reader.readLine();ByteBuffer sendBuffer = ByteBuffer.allocate(256);sendBuffer.clear();if(readMsg.equals("bye")){//告訴伺服器,準備要撤退,當伺服器返回bye close,關閉通道和選取器System.out.println("準備關閉");sendBuffer.put("[email protected]#$%".getBytes());sendBuffer.flip();}else{sendBuffer.put(readMsg.getBytes());sendBuffer.flip();}while (sendBuffer.hasRemaining()) {socketChannel.write(sendBuffer);}}public static void main(String[] args) {NIOClient client = new NIOClient();try {client.initClient("127.0.0.1", 1377);client.listen();} catch (IOException e) {e.printStackTrace();}}}

  用戶端可開啟多個,用於串連伺服器端,親測可用,有問題聯絡作者,[email protected]

商務邏輯可自己完善,其實建議的搭建不難

Java NIO初試

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.