一个简单的nio交互服务,可用命令:date、unix_timestamp、bye、helllo、hi。
主要用于演示,nio的高并发处理应该不是这种方式。
package org.sl.nio.server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
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;
import java.util.Set;
import org.apache.log4j.Logger;
import org.sl.nio.server.handler.NioAcceptableHandler;
import org.sl.nio.server.handler.NioAcceptableHandler1;
import org.sl.nio.server.handler.NioReadableHandler;
/**
*
* @author shanl
*
*/
public class NioServer {
Logger logger = Logger.getLogger(NioServer.class);
String ip = "127.0.0.1";
int port = 7777;
int timeOut = 200;
public void service(){
InetSocketAddress address = null;
ServerSocketChannel ssc = null;
ServerSocket ss = null;
Selector selector = null;
SelectionKey selectkey = null;
Set<SelectionKey> keys = null;
Iterator<SelectionKey> iterator = null;
SelectionKey key = null;
int rc = 0;
SocketChannel sc = null;
try {
address = new InetSocketAddress(ip, port);
ssc = ServerSocketChannel.open();
ss = ssc.socket();
ss.bind(address);
ssc.configureBlocking(false);
System.err.print("NioEchoService listening in "+ip+":"+port+"...\r\n");
// System.out.println();
selector = Selector.open();
selectkey = ssc.register(selector, SelectionKey.OP_ACCEPT );
for(int i=0; i<3; i++){
if((rc = selector.select(timeOut)) > 0) {
// System.out.println("request count: "+rc);
keys = selector.selectedKeys();
iterator = keys.iterator();
while(iterator.hasNext()) {
key = iterator.next();
// System.out.println("operate:"+key.interestOps());
if(key.isAcceptable()){
// System.out.println("isAcceptable");
// new NioAcceptableHandler(key).run();
new Thread(new NioAcceptableHandler1(key)).start();
}
// else if(key.isReadable()){
System.out.println("isReadable");
new NioReadableHandler(key).run();
// new Thread(new NioReadableHandler(key)).start();
// }
//
// if(key.isWritable()){
// continue;
// }
iterator.remove();
}
}else{
System.out.println("time out.");
}
}
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
}
public void setService(String ip, int port) {
this.ip = ip;
this.port = port;
}
public void setServicePort(int port) {
this.port = port;
}
public void setTimeout(int timeout){
this.timeOut = timeout;
}
}
package org.sl.nio.server.handler;
import java.io.IOException;
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.Date;
import java.util.Iterator;
public class NioAcceptableHandler1 implements Runnable{
private SelectionKey key = null;
private SocketChannel sc = null;
private ByteBuffer readBuff = null;
private ByteBuffer writeBuff = null;
private byte[] cmdBuff = null;
private Selector sel = null;
private static final ByteBuffer prompt = ByteBuffer.wrap("\r\n$ >>".getBytes());
private boolean isRun = true;
public NioAcceptableHandler1(SelectionKey key){
try{
this.key = key;
this.sc = ((ServerSocketChannel)key.channel()).accept();
this.readBuff = ByteBuffer.allocate(512);
this.cmdBuff = new byte[512];
this.writeBuff = ByteBuffer.allocate(1024*2);
}catch(Exception ex){
ex.printStackTrace();
}
}
@Override
public void run() {
try {
this.sel = Selector.open();
Iterator<SelectionKey> iter = null;
SelectionKey key = null;
sc.configureBlocking(false);
sc.register(sel,
SelectionKey.OP_READ);
echoWelcome();
echoPrompt();
while(isRun){
if(sel.select(20)>0){
iter = sel.selectedKeys().iterator();
while(iter.hasNext()){
key = iter.next();
if(key.isReadable()){
readable();
// key.interestOps(SelectionKey.OP_WRITE);
}
// else if(key.isWritable()){
// writable();
key.interestOps(SelectionKey.OP_READ);
// }
iter.remove();
}
}
}
sel.wakeup();
sel.close();
sc.close();
} catch (Exception e) {
e.printStackTrace();
}
}
boolean readable()throws Exception{
if(sc.read(readBuff)<=0)return false;
switch(readBuff.get(readBuff.position()-1)){
case 10: //确认,既输入回车
enter();
echoPrompt();
break;
case 0: //
sel.wakeup();
break;
default: //其他字符
}
return true;
}
boolean readable1()throws Exception{
// System.out.println("r");
ByteBuffer tb = ByteBuffer.allocate(32);
int readLen = 0;
byte[] bys = null;
if((readLen = sc.read(tb))>0){
// System.out.println(tb.get(readLen-1));
switch(tb.get(readLen-1)){
case 10: //确认
enter();
echoPrompt();
break;
case 0:
sel.wakeup();
break;
default: //写到buff中
tb.flip();
readBuff.put(tb);
}
}else{
return true;
}
return false;
}
/**
* 用户输入回车
*/
void enter1()throws Exception{
readBuff.flip();
int buffSize = readBuff.limit();
readBuff.get(cmdBuff,0,buffSize);
String cmd = new String(cmdBuff,0,buffSize);
System.out.println("command: "+cmd);
readBuff.clear();
writeBuff.put(cmdBuff,0,buffSize);
writeBuff.put("\r\nok.\r\n".getBytes());
writeBuff.flip();
sc.write(writeBuff);
writeBuff.clear();
}
/**
* 用户输入回车
* @throws Exception
*/
void enter()throws Exception{
readBuff.flip();
int buffSize = readBuff.limit();
readBuff.get(cmdBuff,0,buffSize);
String cmd = new String(cmdBuff,0,buffSize);
System.out.println("command: "+cmd+"");
readBuff.clear();
String res = parseCommand(cmd);
sc.write(ByteBuffer.wrap(res.getBytes()));
if("\r\nbye bye.\r\n".equals(res)){
this.isRun = false;
}
}
String parseCommand(String cmd){
String res = null;
if(cmd.startsWith("date")){
res = new Date().toString();
}else if(cmd.startsWith("unix_timestamp")){
res = System.currentTimeMillis()+"";
}else if(cmd.startsWith("hello") || cmd.startsWith("hi")){
res = "hi";
}else if(cmd.startsWith("bye")){
res = "bye bye.";
}else{
res = "unknown command.";
}
return "\r\n"+res+"\r\n";
}
void writable2()throws Exception{
readBuff.flip();
int buffSize = readBuff.limit();
readBuff.get(cmdBuff,0,buffSize);
String cmd = new String(cmdBuff,0,buffSize);
System.out.println("command: "+cmd);
readBuff.flip();
sc.write(readBuff);
readBuff.clear();
}
void echoWelcome()throws Exception{
sc.write(ByteBuffer.wrap("welcome to NioEchoServer.\r\n".getBytes()));
}
void echoPrompt()throws Exception{
if(isRun) {
sc.write(prompt);
prompt.flip();
}
}
}
import org.sl.nio.server.NioServer;
public class NioServerTest {
public static void main(String[] args){
t1();
}
static void t1(){
NioServer nserver = new NioServer();
nserver.setService("192.168.2.23", 7777);
nserver.setTimeout(0);
nserver.service();
}
}