问题描述
packagecom.laos.server;importjava.io.IOException;importjava.net.InetSocketAddress;importjava.net.ServerSocket;importjava.nio.channels.SelectionKey;importjava.nio.channels.Selector;importjava.nio.channels.ServerSocketChannel;importjava.nio.channels.SocketChannel;importjava.util.Iterator;importjava.util.Set;importcom.laos.core.ReflectionUtils;importcom.laos.core.config.Configurabe;importcom.laos.core.config.DefaultConfigure;importcom.laos.core.pool.ThreadPool;importcom.laos.core.pool.ThreadPoolUtils;importcom.laos.core.rw.Reader;importcom.laos.core.rw.Writer;/***socketserver,采用非阻塞方式**@authorshuzt**/publicclassNIOServerSocket{privateConfigurabedefaultConfig;privatefinalThreadPoolreader;privatefinalThreadPoolwriter;privatefinalClassreador;privatefinalClasswritor;/***私有构造器**/privateNIOServerSocket(){defaultConfig=newDefaultConfigure();reader=ThreadPoolUtils.getReadThreadPool(defaultConfig);writer=ThreadPoolUtils.getWriteThreadPool(defaultConfig);StringreadClassName=defaultConfig.get("Reader.class");StringwriteClassName=defaultConfig.get("Writer.class");reador=ReflectionUtils.getClass(readClassName);writor=ReflectionUtils.getClass(writeClassName);if(!Reader.class.isAssignableFrom(reador)||!Writer.class.isAssignableFrom(writor)){System.err.print(reador.getName()+"与"+Reader.class.getName()+"非父子类关系");System.err.println("或"+writor.getName()+"与"+Writer.class.getName()+"非父子类关系");System.exit(-1);}}/***实例*/privatestaticfinalNIOServerSocketserver=newNIOServerSocket();/***获取server实例**@return*/publicstaticNIOServerSocketgetInstance(){returnserver;}/***启动socketserver**@throwsIOException*@throwsNumberFormatException**/publicvoidstart()throwsNumberFormatException,IOException{//获取端口Stringport=defaultConfig.get("server.socket.port");run(Integer.parseInt(port));}privatevoidrun(intport)throwsIOException{ServerSocketChannelchannle=ServerSocketChannel.open();//设置阻塞方式channle.configureBlocking(Boolean.parseBoolean(defaultConfig.get("server.socket.blocking")));Selectorselector=Selector.open();channle.register(selector,SelectionKey.OP_ACCEPT);ServerSocketserver=channle.socket();server.setReceiveBufferSize(Integer.parseInt(defaultConfig.get("server.socket.receiveBufferSize")));server.setReuseAddress(Boolean.parseBoolean(defaultConfig.get("server.socket.reuseAddress")));InetSocketAddressaddr=newInetSocketAddress(port);server.bind(addr);Class[]paraType={Selector.class,SocketChannel.class};while(!Thread.interrupted()){intacceptNum=selector.select();System.out.println("acceptNum===="+acceptNum);if(acceptNum>0){Setkeys=selector.selectedKeys();System.out.println("selectedKeys===="+keys.size());Iteratoritr=keys.iterator();while(itr.hasNext()){SelectionKeyselectKey=(SelectionKey)itr.next();if(selectKey.isAcceptable()){//连接ServerSocketChannelchannel=(ServerSocketChannel)selectKey.channel();SocketChannelsocket=channel.accept();socket.configureBlocking(false);socket.register(selector,SelectionKey.OP_READ);}elseif(selectKey.isReadable()){//读操作SocketChannelchannel=(SocketChannel)selectKey.channel();Object[]parameter={selector,channel};Objectreadclass;try{readclass=ReflectionUtils.newInstanceByConstructor(reador,paraType,parameter);reader.submit((Reader)readclass);}catch(Exceptione){e.printStackTrace();}System.out.println("OP_READ");}elseif(selectKey.isWritable()){//写操作System.out.println("OP_WRITE");SocketChannelchannel=(SocketChannel)selectKey.channel();Object[]parameter={selector,channel};Objectwriteclass;try{writeclass=ReflectionUtils.newInstanceByConstructor(writor,paraType,parameter);writer.submit((Writer)writeclass);}catch(Exceptione){e.printStackTrace();}}selectKey.cancel();itr.remove();}keys.clear();}}}publicstaticvoidmain(String[]args){try{NIOServerSocket.getInstance().start();}catch(IOExceptione){}}}packagecom.laos.core.rw.impl;importjava.io.IOException;importjava.nio.ByteBuffer;importjava.nio.channels.SelectionKey;importjava.nio.channels.Selector;importjava.nio.channels.SocketChannel;importjava.util.Calendar;importcom.laos.core.rw.Reader;/***默认读写操作*@authorshuzt**/publicclassDefaultReaderextendsReader{publicDefaultReader(Selectorselector,SocketChannelchannal){super(selector,channal);}@Overrideprotectedvoidread(Selectorselector,SocketChannelchannal){ByteBufferbuffer=ByteBuffer.allocate(1024);try{channal.read(buffer);System.out.println(Calendar.getInstance().getTime()+"DefaultReader");channal.register(selector,SelectionKey.OP_WRITE);System.out.println("finishreadoperation");}catch(IOExceptione){e.printStackTrace();}}}程序走到//读操作之后就不动了,按理说我在read操作后将socketchannle注册为write就会继续往下走啊?