服务端代码
package net.nio; import java.io.ByteArrayOutputStream; 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 MyServer { /** * @Title: 使用NIO实现Socket通信服务器端 * @Description: TODO(这里用一句话描述这个方法的作用) * @param @param args 设定文件 * @return void 返回类型 * @throws */ public static void main(String[] args) { // TODO Auto-generated method stub Selector selector = null; ServerSocketChannel serverSocketChannel = null; try { //开启IO多路复用轮询 selector = Selector.open(); serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false);//必须配置为非阻塞 serverSocketChannel.socket().setReuseAddress(true);//设置当连接处于超时状态时,是否允许新的连接使用旧的连接端口 serverSocketChannel.socket().bind(new InetSocketAddress(10000));//绑定服务器本地地址和端口 //在多路复用轮询器上注册操作 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("server is ready............."); while(selector.select()>0){ //取得就绪操作 Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while(it.hasNext()){ SelectionKey readyKey = it.next(); it.remove(); execute((ServerSocketChannel)readyKey.channel()); } } System.out.println("server is over............."); }catch (IOException e) { throw new RuntimeException(e.getMessage(),e); }finally{ try { selector.close(); } catch (IOException e) { throw new RuntimeException(e.getMessage(),e); } try { serverSocketChannel.close(); } catch (IOException e) { throw new RuntimeException(e.getMessage(),e); } } } /***/ private static void execute(ServerSocketChannel serverSocketChannel)throws IOException{ SocketChannel socketChannel = null; try{ //收到客户端请求信息 socketChannel = serverSocketChannel.accept(); RequestObject requestObject = receiveData(socketChannel); System.out.println("receive from Client:"+requestObject.toString()); //发生响应信息到客户端 ResponseObject responseObject = new ResponseObject("response for "+requestObject.getName(), "response for "+requestObject.getValue()); sendData(socketChannel,responseObject); }finally{ socketChannel.close(); } } private static RequestObject receiveData(SocketChannel socketChannel)throws IOException{ RequestObject requestObject = null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteBuffer buffer = ByteBuffer.allocate(1024); try{ byte[] bytes; int size = 0; while((size=socketChannel.read(buffer))>=0){ //反转指针,由写状态到读状态 buffer.flip(); bytes = new byte[size]; buffer.get(bytes); bos.write(bytes); buffer.clear(); } bytes = bos.toByteArray(); Object result = ClassUtil.bytes2Object(bytes); requestObject = (RequestObject)result; }finally{ bos.close(); } return requestObject; } private static void sendData(SocketChannel socketChannel,ResponseObject responseObject)throws IOException{ byte[] bytes = ClassUtil.object2Bytes(responseObject); ByteBuffer buffer = ByteBuffer.wrap(bytes); socketChannel.write(buffer); } }
客户端调用代码
package net.nio; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; public class MyClient { /** * @Title: NIO客户端,发生消息 * @Description: 启动100个线程给服务端发消息 * @param @param args 设定文件 * @return void 返回类型 * @throws */ public static void main(String[] args) { // TODO Auto-generated method stub for(int i=0;i<100;i++){ final int idx = i; new Thread(new MyRunnable(idx)).start(); } } } class MyRunnable implements Runnable{ private final int idx; public MyRunnable(int idx){ this.idx = idx; } @Override public void run() { SocketChannel socketChannel = null; try{ //连接服务器 socketChannel = SocketChannel.open(); SocketAddress remoteAddress = new InetSocketAddress("127.0.0.1",10000); socketChannel.connect(remoteAddress); //发送请求 RequestObject requestObject = new RequestObject("request_"+idx,"request_"+idx); sendData(socketChannel,requestObject); //接收响应 ResponseObject responseObject = receiveData(socketChannel); System.out.println("reveive from server:"+responseObject.toString()); }catch (IOException e) { throw new RuntimeException(e.getMessage(),e); }finally{ try { socketChannel.close(); } catch (IOException e) { throw new RuntimeException(e.getMessage(),e); } } } private void sendData(SocketChannel socketChannel,RequestObject requestObject)throws IOException{ byte[] bytes = ClassUtil.object2Bytes(requestObject); ByteBuffer buffer = ByteBuffer.wrap(bytes); socketChannel.write(buffer); //结束输出 socketChannel.socket().shutdownOutput(); } private ResponseObject receiveData(SocketChannel socketChannel)throws IOException{ ResponseObject responseObject = null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); try{ ByteBuffer buffer = ByteBuffer.allocate(1024); byte[] bytes; int size=0; while((size=socketChannel.read(buffer))>=0){ buffer.flip(); bytes = new byte[size]; buffer.get(bytes); bos.write(bytes); buffer.clear(); } bytes = bos.toByteArray(); responseObject = (ResponseObject) ClassUtil.bytes2Object(bytes); //结束读入 socketChannel.socket().shutdownInput(); }finally{ bos.close(); } return responseObject; } }
工具类
package net.nio; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; /** * 操作class的工具类,包括序列化,反序列化,获取类信息 * */ public class ClassUtil { //用于缓存类的Field信息 private static ConcurrentHashMap<String, List<Field>> classFieldMap = new ConcurrentHashMap<String,List<Field>>(); //用于缓存类的Field信息 private static ConcurrentHashMap<String,Method[]> classMethodMap = new ConcurrentHashMap<String,Method[]>(); /** * 序列化 * @param object 需要序列化的对象 * */ public static byte[] object2Bytes(Object object){ ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = null; try{ oos = new ObjectOutputStream(baos); oos.writeObject(object); }catch(IOException e){ throw new RuntimeException(e.getMessage(),e); }finally{ try { if(oos!=null) oos.close(); } catch (IOException e) { throw new RuntimeException(e.getMessage(),e); } } return baos.toByteArray(); } /** * 反序列化 * @param bytes 需要反序列化成对象的字节数组 * */ public static Object bytes2Object(byte[] bytes){ ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = null; try{ ois = new ObjectInputStream(bis); Object object = ois.readObject(); return object; }catch(IOException e){ throw new RuntimeException(e.getMessage(),e); } catch (ClassNotFoundException e) { throw new RuntimeException(e.getMessage(),e); }finally{ if(ois!=null){ try { ois.close(); } catch (IOException e) { throw new RuntimeException(e.getMessage(),e); } } } } }
ResponseObject和RequestObject就是简单的java bean,因为字数研制,就不给出了。