server:
package com.io;
import com.mysql.fabric.Server;
import java.net.InetSocketAddress;
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.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NioServer {
Selector selector;
ServerSocketChannel ssc;
private ExecutorService service = Executors.newFixedThreadPool(5);
public void init() {
try {
ssc= ServerSocketChannel.open();
ssc.bind(new InetSocketAddress("127.0.0.1",7878));
ssc.configureBlocking(false);
selector= Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("server....start.....");
}catch (Exception e){
e.printStackTrace();
}
}
public void accept(SelectionKey selectionKey){
try {
ServerSocketChannel scc = (ServerSocketChannel) selectionKey.channel();
SocketChannel sc = scc.accept();
sc.configureBlocking(false);
sc.register(selector,SelectionKey.OP_READ);
System.out.println("=====acceptfinish==========="+sc.socket().getInetAddress().getHostName());
}catch (Exception e){
e.printStackTrace();
System.out.println("===============================");
}
}
public void start(){
init();
while (true){
System.out.println("1111111111111111111111111111111111111");
try {
int event = selector.select();
if (event >= 1) {
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
System.out.println("2222222222222222222222222222222222222222222");
SelectionKey selectionKey = it.next();
if(selectionKey.isAcceptable()){
System.out.println("=========接受======");
accept(selectionKey);
}else if(selectionKey.isReadable()){
System.out.println("====read========="+selectionKey.isReadable());
service.submit(new HandleSocket(selectionKey));
Thread.sleep(5000);
System.out.println("============沉睡结束==========");
}
it.remove();
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new NioServer().start();
}
}
client:
package com.io;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NioClient {
private Selector selector;
public void connect(){
try {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
this.selector = Selector.open();
// 为通道注册连接事件,当该事件到达时,selector.select()会返回
socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(new InetSocketAddress("127.0.0.1",7878));
}catch (Exception e){
e.printStackTrace();
System.out.println("=============err==================");
}
}
public Selector getSelector() {
return selector;
}
public void setSelector(Selector selector) {
this.selector = selector;
}
public static void main(String[] args) {
ExecutorService es = Executors.newFixedThreadPool(5);
for(int i=0;i<1;i++){
es.submit(new Runnable() {
@Override
public void run() {
NioClient nioClient = new NioClient();
nioClient.connect();
nioClient.runHandle();
}
});
}
}
public void runHandle(){
try {
while (true) {
int event = selector.select();
if (event >= 1) {
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey selectionKey = it.next();
it.remove();
if (selectionKey.isConnectable()) {
System.out.println();
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
if (socketChannel.isConnectionPending()) {
socketChannel.finishConnect();
}
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ);
System.out.println("==============================");
ByteBuffer bf = ByteBuffer.allocate(1024);
bf.put("Hi,server,i'm client".getBytes());
bf.flip();
while (bf.hasRemaining()){
socketChannel.write(bf);
}
} else {
System.out.println("==读取==" + selectionKey.isReadable());
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
socketChannel.read(byteBuffer);
System.out.println("读取到数据==" + new String(byteBuffer.array()));
socketChannel.close();
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
其中遇到问题:client断开,server还会接收到空数据。原因是 while(true)一直再刷,刷到read丢给了一个线程去执行,然后接着刷,有可能会刷到上一个selectkey…在刷到后加个sleep就不会出现问题了,,一般是在刷到后去注销读事件。。。所以后面加了个sleep。