java nio 實現客戶端與服務端讀寫
阿新 • • 發佈:2019-01-22
剛開始寫,有待後續完善
服務端程式碼:
package com.geng.test3; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class Server { private static Selector selector ; public static void init() throws IOException{ selector = Selector.open(); ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); ssc.bind(new InetSocketAddress(InetAddress.getLocalHost(), 8099)); ssc.register(selector, SelectionKey.OP_ACCEPT); } public static void listen() throws IOException{ while(true){ int select = selector.select(); if(select == 0){ continue; } Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> it = selectedKeys.iterator(); while(it.hasNext()){ SelectionKey key = it.next(); // 由於select操作只管對selectedKeys進行新增,所以key處理後我們需要從裡面把key去掉 it.remove(); if(key.isAcceptable()){ ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); // 得到與客戶端的套接字通道 SocketChannel channel = serverChannel.accept(); channel.configureBlocking(false); // 同樣將於客戶端的通道在selector上註冊,,可以通過key獲取關聯的選擇器 channel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE); }else if(key.isReadable()){ read(key); // 改變自身關注事件,可以用位或操作|組合時間 key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE); }else if(key.isWritable()){ write(key); // 改變自身關注事件,可以用位或操作|組合時間 key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE); } } } } private static void write(SelectionKey key) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); channel.write(ByteBuffer.wrap("server write".getBytes())); } private static void read(SelectionKey key) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); int count = channel.read(buffer); byte[] bytes = new byte[count]; buffer.flip(); buffer.get(bytes); //System.out.println(new String(bytes)); } public static void main(String[] args) throws IOException { init(); listen(); } }
客戶端程式碼:
package com.geng.test3; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class Client { private static Selector selector; public static void init() throws IOException{ selector = Selector.open(); SocketChannel sc = SocketChannel.open(); sc.configureBlocking(false); sc.connect(new InetSocketAddress(InetAddress.getLocalHost(), 8099)); sc.register(selector, SelectionKey.OP_CONNECT); } public static void listen() throws IOException{ while(true){ selector.select(); Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> it = selectedKeys.iterator(); while(it.hasNext()){ SelectionKey key = it.next(); it.remove(); if(key.isConnectable()){ SocketChannel channel = (SocketChannel) key.channel(); if(channel.finishConnect()){ channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE); } }else if(key.isReadable()){ read(key); // 改變自身關注事件,可以用位或操作|組合時間 key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE); }else if(key.isWritable()){ write(key); // 改變自身關注事件,可以用位或操作|組合時間 key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE); } } } } private static void write(SelectionKey key) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); channel.write(ByteBuffer.wrap("server write".getBytes())); } private static void read(SelectionKey key) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); int count = channel.read(buffer); byte[] bytes = new byte[count]; buffer.flip(); buffer.get(bytes); System.out.println(new String(bytes)); } }