2. 简单的加法server和客户机
server代码
package examples.nio; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.net.InetSocketAddress; import java.io.IOException; /** * SumServer.java * * * Created: Thu Nov 06 11:41:52 2003 * * @author starchu1981 * @version 1.0 */ public class SumServer { private ByteBuffer _buffer=ByteBuffer.allocate(8); private IntBuffer _intBuffer=_buffer.asIntBuffer(); private SocketChannel _clientChannel=null; private ServerSocketChannel _serverChannel=null; public void start(){ try{ openChannel(); waitForConnection(); }catch(IOException e){ System.err.println(e.toString()); } } private void openChannel()throws IOException{ _serverChannel=ServerSocketChannel.open(); _serverChannel.socket().bind(new InetSocketAddress(10000)); System.out.println("server通道已经打开"); } private void waitForConnection()throws IOException{ while(true){ _clientChannel=_serverChannel.accept(); if(_clientChannel!=null){ System.out.println("新的连接增加"); processRequest(); _clientChannel.close(); } } } private void processRequest()throws IOException{ _buffer.clear(); _clientChannel.read(_buffer); int result=_intBuffer.get(0)+_intBuffer.get(1); _buffer.flip(); _buffer.clear(); _intBuffer.put(0,result); _clientChannel.write(_buffer); } public static void main(String [] args){ new SumServer().start(); } } // SumServer 客户代码 package examples.nio; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.channels.SocketChannel; import java.net.InetSocketAddress; import java.io.IOException; /** * SumClient.java * * * Created: Thu Nov 06 11:26:06 2003 * * @author starchu1981 * @version 1.0 */ public class SumClient { private ByteBuffer _buffer=ByteBuffer.allocate(8); private IntBuffer _intBuffer; private SocketChannel _channel; public SumClient() { _intBuffer=_buffer.asIntBuffer(); } // SumClient constructor public int getSum(int first,int second){ int result=0; try{ _channel=connect(); sendSumRequest(first,second); result=receiveResponse(); }catch(IOException e){System.err.println(e.toString()); }finally{ if(_channel!=null){ try{ _channel.close(); }catch(IOException e){} } } return result; } private SocketChannel connect()throws IOException{ InetSocketAddress socketAddress= new InetSocketAddress("localhost",10000); return SocketChannel.open(socketAddress); } private void sendSumRequest(int first,int second)throws IOException{ _buffer.clear(); _intBuffer.put(0,first); _intBuffer.put(1,second); _channel.write(_buffer); System.out.println("发送加法请求 "+first+"+"+second); } private int receiveResponse()throws IOException{ _buffer.clear(); _channel.read(_buffer); return _intBuffer.get(0); } public static void main(String [] args){ SumClient sumClient=new SumClient(); System.out.println("加法结果为 :"+sumClient.getSum(100,324)); } } // SumClient |
3. 非堵塞的加法server
首先在openChannel方法中增加语句
_serverChannel.configureBlocking(false);//设置成为非堵塞模式
重写WaitForConnection方法的代码例如以下,使用非堵塞方式
private void waitForConnection()throws IOException{ Selector acceptSelector = SelectorProvider.provider().openSelector(); /*在server套接字上注冊selector并设置为接受accept方法的通知。 这就告诉Selector,套接字想要在accept操作发生时被放在ready表 上,因此,同意多元非堵塞I/O发生。*/ SelectionKey acceptKey = ssc.register(acceptSelector, SelectionKey.OP_ACCEPT); int keysAdded = 0; /*select方法在不论什么上面注冊了的操作发生时返回*/ while ((keysAdded = acceptSelector.select()) > 0) { // 某客户已经准备好能够进行I/O操作了,获取其ready键集合 Set readyKeys = acceptSelector.selectedKeys(); Iterator i = readyKeys.iterator(); // 遍历ready键集合,并处理加法请求 while (i.hasNext()) { SelectionKey sk = (SelectionKey)i.next(); i.remove(); ServerSocketChannel nextReady = (ServerSocketChannel)sk.channel(); // 接受加法请求并处理它 _clientSocket = nextReady.accept().socket(); processRequest(); _clientSocket.close(); } } } |