基本概念:参考http://zhangshixi.iteye.com/blog/679959作者的系列文章即可
NIO因为其高效性,成为了服务端的首选,大大提高了服务端的响应效率。
我自己读完作者的文章,写了一个简单的DEMO
服务端:
客户端:
NIO因为其高效性,成为了服务端的首选,大大提高了服务端的响应效率。
我自己读完作者的文章,写了一个简单的DEMO
服务端:
package com.liuc.io;
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.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;
import org.apache.log4j.Logger;
public class NIOServer extends Thread {
private Logger log=Logger.getLogger(NIOServer.class);
private boolean stop=false;
private String ip="localhost";
private int port=9999;
private Selector selector;
private ByteBuffer buffer=ByteBuffer.allocate(1024);
private Charset gbkCharset = Charset.forName( "GB2312" );
public NIOServer() {
try {
selector=Selector.open();
ServerSocketChannel ssc=ServerSocketChannel.open();
InetSocketAddress address=new InetSocketAddress(ip, port);
//ServerSocket绑定IP
ssc.socket().bind(address);
//设置为非阻塞模式
ssc.configureBlocking(false);
//向选择器注册
ssc.register(selector,SelectionKey.OP_ACCEPT);
System.out.println("Listen to port:"+port);
} catch (IOException e) {
log.error(e);
}
}
@Override
public void run() {
System.out.println("deal with request");
while(!stop){
String content="HelloWorld";
try {
int numKeys = selector.select();
Set<SelectionKey> selectionKeys=selector.selectedKeys();
Iterator<SelectionKey> iterator=selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
dealRequest(key,content);
}
} catch (IOException e) {
log.equals(e);
}
}
}
private void dealRequest(SelectionKey key,String contentToSend) {
try {
StringBuffer clientContent=new StringBuffer();
if(key.isAcceptable()){//测试此键的通道是否已准备好接受新的套接字连接。
ServerSocketChannel ssc=(ServerSocketChannel) key.channel();
SocketChannel sc=ssc.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey. OP_READ);
}else if(key.isReadable()) {//测试此键的通道是否已准备好进行读取。
SocketChannel sc=(SocketChannel) key.channel();
while(true){//读取全部数据
buffer.clear();
int r=sc.read(buffer);
buffer.flip();
byte[] temp=new byte[r];
if (r<=0) {
break;
}
clientContent.append(gbkCharset.decode(buffer).toString());
}
//获取全部的数据
String content=clientContent.toString();
String[] info=content.split(",");//用户名密码验证
System.out.println("客户端的验证请求为:"+content);
sc.register(selector, SelectionKey.OP_WRITE);
}else if(key.isWritable()){//测试此键的通道是否已准备好进行写入
System.out.println("要发送的消息为"+contentToSend);
buffer.clear();
buffer.put(contentToSend.getBytes());
buffer.flip();
SocketChannel sc = (SocketChannel)key.channel();
sc.write(buffer);
buffer.flip();
//发送完信息后关闭连接
key.cancel();
sc.close();
}
} catch (IOException e) {
System.out.println(e);
//客户端断开连接,所以从Selector中取消注册
key.cancel();
if(key.channel() != null)
try {
key.channel().close();
log.debug("the client socket is closed!");
//System.out.println("the client socket is closed!");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public static void main(String[] args){
new NIOServer().start();
}
}
客户端:
package com.liuc.io;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class NIOClient {
/**
* @param args
*/
public static void main(String[] args) {
Socket socket=null;
OutputStream outputStream=null;
InputStream inputStream=null;
try {
socket=new Socket("localhost", 9999);
outputStream=socket.getOutputStream();
String sendContent="HelloWorld";
outputStream.write(sendContent.getBytes());
outputStream.flush();
inputStream=socket.getInputStream();
byte[] bytes=new byte[1024];
int n=inputStream.read(bytes);
System.out.println(new String(bytes));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(inputStream!=null){
inputStream.close();
}
if (outputStream!=null) {
outputStream.close();
}
if (socket!=null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}