基本概念:参考http://zhangshixi.iteye.com/blog/679959作者的系列文章即可
我自己读完作者的文章,写了一个简单的DEMO
服务端:
Java代码 收藏代码
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();
}
}
[size=medium]客户端:[/size]
<pre class="java" name="code">
</pre>
<br>package com.liuc.io;
<br>
<br>import java.io.IOException;
<br>import java.io.InputStream;
<br>import java.io.OutputStream;
<br>import java.net.Socket;
<br>import java.net.UnknownHostException;
<br>
<br>public class NIOClient {
<br>
<br> /**
<br> * @param args
<br> */
<br> public static void main(String[] args) {
<br> Socket socket=null;
<br> OutputStream outputStream=null;
<br> InputStream inputStream=null;
<br> try {
<br> socket=new Socket("localhost", 9999);
<br> outputStream=socket.getOutputStream();
<br> String sendContent="HelloWorld";
<br> outputStream.write(sendContent.getBytes());
<br> outputStream.flush();
<br>
<br>
<br> inputStream=socket.getInputStream();
<br> byte[] bytes=new byte[1024];
<br> int n=inputStream.read(bytes);
<br> System.out.println(new String(bytes));
<br>
<br>
<br> } catch (UnknownHostException e) {
<br> e.printStackTrace();
<br> } catch (IOException e) {
<br> e.printStackTrace();
<br> }finally{
<br> try {
<br> if(inputStream!=null){
<br> inputStream.close();
<br> }
<br> if (outputStream!=null) {
<br> outputStream.close();
<br> }
<br> if (socket!=null) {
<br> socket.close();
<br> }
<br> } catch (IOException e) {
<br> e.printStackTrace();
<br> }
<br>
<br> }
<br>
<br>
<br> }
<br>
<br>}
<br>
我自己读完作者的文章,写了一个简单的DEMO
服务端:
Java代码 收藏代码
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();
}
}
[size=medium]客户端:[/size]
<pre class="java" name="code">
</pre>
<br>package com.liuc.io;
<br>
<br>import java.io.IOException;
<br>import java.io.InputStream;
<br>import java.io.OutputStream;
<br>import java.net.Socket;
<br>import java.net.UnknownHostException;
<br>
<br>public class NIOClient {
<br>
<br> /**
<br> * @param args
<br> */
<br> public static void main(String[] args) {
<br> Socket socket=null;
<br> OutputStream outputStream=null;
<br> InputStream inputStream=null;
<br> try {
<br> socket=new Socket("localhost", 9999);
<br> outputStream=socket.getOutputStream();
<br> String sendContent="HelloWorld";
<br> outputStream.write(sendContent.getBytes());
<br> outputStream.flush();
<br>
<br>
<br> inputStream=socket.getInputStream();
<br> byte[] bytes=new byte[1024];
<br> int n=inputStream.read(bytes);
<br> System.out.println(new String(bytes));
<br>
<br>
<br> } catch (UnknownHostException e) {
<br> e.printStackTrace();
<br> } catch (IOException e) {
<br> e.printStackTrace();
<br> }finally{
<br> try {
<br> if(inputStream!=null){
<br> inputStream.close();
<br> }
<br> if (outputStream!=null) {
<br> outputStream.close();
<br> }
<br> if (socket!=null) {
<br> socket.close();
<br> }
<br> } catch (IOException e) {
<br> e.printStackTrace();
<br> }
<br>
<br> }
<br>
<br>
<br> }
<br>
<br>}
<br>