1、例: EchoServer.java(非阻塞模式) import java.io.*; import java.nio.*; import java.nio.channels.*; import java.nio.charset.*; import .*; import java.util.*; public class EchoServer private Selector selector = null; private ServerSocketChannel serverSocketChannel = null; private int port = 8000; private Char
2、set charset = Charset.forName(“GBK“); public EchoServer() throws IOException selector = Selector.open(); serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().setReuseAddress(true);serverSocketChannel.configureBlocking(false); serverSocketChannel.socket().bind(new InetSocket
3、Address(port); System.out.println(“服务器启动“); public void service() throws IOException serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while( selector.select() 0 ) Set readyKeys = selector.selectedKeys(); Iterator it = readyKeys.iterator(); while( it.hasNext() ) SelectionKey key = null
4、; try key = (SelectionKey)it.next(); it.remove(); if( key.isAcceptable() ) ServerSocketChannel ssc = (ServerSocketChannel)key.channel(); SocketChannel socketChannel = (SocketChannel)ssc.accept(); System.out.println(“接收到客户连接,来自:“ + socketChannel.socket().getInetAddress() + “:“ + socketChannel.socket(
5、).getPort(); socketChannel.configureBlocking(false); ByteBuffer buffer = ByteBuffer.allocate(1024);socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, buffer); if( key.isReadable() ) receive(key); if( key.isWritable() ) send(key); catch( IOException e ) e.printStackTrace()
6、; try if( key != null ) key.cancel(); key.channel().close(); catch( Exception ex ) e.printStackTrace(); /#while /#while public void send(SelectionKey key) throws IOException ByteBuffer buffer = (ByteBuffer)key.attachment(); SocketChannel socketChannel = (SocketChannel)key.channel(); buffer.flip(); /
7、把极限设为位置,把位置设为 0 String data = decode(buffer); if( data.indexOf(“/r/n“) = -1 ) return; String outputData = data.substring(0, data.indexOf(“/n“) + 1); System.out.print(outputData); ByteBuffer outputBuffer = encode(“echo:“ + outputData); /发送一行字符串 while( outputBuffer.hasRemaining() ) socketChannel.write
8、(outputBuffer); ByteBuffer temp = encode(outputData); buffer.position(temp.limit(); pact(); /删除已经处理的字符串 if( outputData.equals(“bye/r/n“) ) key.cancel(); socketChannel.close(); System.out.println(“关闭与客户的连接“); public void receive(SelectionKey key) throws IOException ByteBuffer buffer = (ByteBuffer)key
9、.attachment(); SocketChannel socketChannel = (SocketChannel)key.channel(); ByteBuffer readBuff = ByteBuffer.allocate(32); socketChannel.read(readBuff); readBuff.flip(); buffer.limit(buffer.capacity(); buffer.put(readBuff); /把读到的数据放到 buffer 中 public String decode(ByteBuffer buffer) /解码 CharBuffer cha
10、rBuffer = charset.decode(buffer); return charBuffer.toString(); public ByteBuffer encode(String str) /编码 return charset.encode(str); public static void main(String args) throws Exception EchoServer server = new EchoServer(); server.service(); 例程 EchoClient.java(非阻塞模式) import .*; import java.nio.chan
11、nels.*; import java.nio.*; import java.io.*; import java.nio.charset.*; import java.util.*; public class EchoClient private SocketChannel socketChannel = null; private ByteBuffer sendBuffer = ByteBuffer.allocate(1024); private ByteBuffer receiveBuffer = ByteBuffer.allocate(1024); private Charset cha
12、rset = Charset.forName(“GBK“); /字符采用 GBK 编码,创建了一个代表“GBK”编码的 Charset 对象private Selector selector; public EchoClient() throws IOException socketChannel = SocketChannel.open(); InetAddress ia = InetAddress.getLocalHost(); InetSocketAddress isa = new InetSocketAddress(ia, 8000);socketChannel.connect(isa
13、); /采用阻塞模式连接服务器 socketChannel.configureBlocking(false); /设置为非阻塞模式 System.out.println(“与服务器的连接建立成功“); selector = Selector.open(); public static void main(String args) throws IOException final EchoClient client = new EchoClient(); Thread receiver = new Thread() /创建 Receiver 线程 public void run() client
14、.receiveFromUser(); /接收用户向控制台输入的数据 ; receiver.start(); /启动 Receiver 线程 client.talk(); public void receiveFromUser() /接收用户从控制台输入的数据,把它放到 sendBuffer 中 try BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in); /键盘接受字符串行String msg = null; while( (msg = localReader.readLine()
15、!= null ) synchronized(sendBuffer) sendBuffer.put(encode(msg + “/r/n“); if( msg.equals(“bye“) ) break; catch( IOException e ) e.printStackTrace(); public void talk() throws IOException /接收和发送数据 socketChannel.register(selector, SelectionKey.OP_READ |SelectionKey.OP_WRITE); while( selector.select() 0
16、) Set readyKeys = selector.selectedKeys(); Iterator it = readyKeys.iterator(); while( it.hasNext() ) SelectionKey key = null; try key = (SelectionKey)it.next(); it.remove(); if( key.isReadable() ) receive(key); if( key.isWritable() ) send(key); catch( IOException e ) e.printStackTrace(); try if( key
17、 != null ) key.cancel(); key.channel().close(); catch( Exception ex ) e.printStackTrace(); /#while /#while public void send(SelectionKey key) throws IOException /发送 sendBuffer 中的数据 SocketChannel socketChannel = (SocketChannel)key.channel(); synchronized(sendBuffer) sendBuffer.flip(); /把极限设为位置,把位置设为零
18、 socketChannel.write(sendBuffer); /发送数据 sendBpact(); /删除已经发送的数据 public void receive(SelectionKey key) throws IOException /接收 EchoServer 发送的数据,把它放到 receiveBuffer 中/如果 receiveBuffer 中有一行数据,就打印这行数据,然后把它从 receiveBuffer 中删除 SocketChannel socketChannel = (SocketChannel)key.channel(); socketChannel.read(re
19、ceiveBuffer); receiveBuffer.flip(); String receiveData = decode(receiveBuffer); /解码if( receiveData.indexOf(“/n“) = -1 ) return; String outputData = receiveData.substring(0, receiveData.indexOf(“/n“) + 1); System.out.print(outputData); if( outputData.equals(“echo:bye/r/n“) ) key.cancel(); socketChann
20、el.close(); System.out.println(“关闭与服务器的连接“); selector.close(); System.exit(0); /结束程序 ByteBuffer temp = encode(outputData); receiveBuffer.position(temp.limit(); receiveBpact(); /删除已经打印的数据 public String decode(ByteBuffer buffer) /解码 CharBuffer charBuffer = charset.decode(buffer); return charBuffer.toString(); public ByteBuffer encode(String str) /编码 return charset.encode(str);