客户端代码
package NIO;
import java.net.InetSocketAddress;
import java.nio.*;
import java.nio.channels.*;
import java.util.Date;
public class Client {
public static void main(String[] args) throws Exception {
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8080));
socketChannel.configureBlocking(false);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(true) {
Thread.sleep(1000);
buffer.put(new Date().toString().getBytes());
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
}
}
服务器端代码
package NIO;
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.util.Date;
import java.util.Iterator;
import java.util.Set;
public class Server {
public static void main(String[] args) throws Exception {
//打开socketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//设定地址以及端口号
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);
//绑定端口
serverSocketChannel.bind(inetSocketAddress);
//设置为非阻塞同步IO
serverSocketChannel.configureBlocking(false);
//获取Buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
//选择器相关
//打开选择器
Selector selector = Selector.open();
//将ServerSocketChannel注册到selector中,状态设置为OP_ACCEPT
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println(new Date().toString() + "服务器启动");
//轮询
while (selector.select() > 0) {
//selectionKeys中包含所有注册到selector中的管道对象
Set<SelectionKey> selectionKeys = selector.selectedKeys();
//需要遍历selector 集合中的所有管道对象,根据管道对象的状态编写不同的业务逻辑。
Iterator<SelectionKey> selectionKeyIterator = selectionKeys.iterator();
//遍历selectionKeys集合
while (selectionKeyIterator.hasNext()) {
SelectionKey next = selectionKeyIterator.next();
if (next.isAcceptable()) {
//如果有客户端连接了,进行连接对应的操作,就为客户端建立管道,并且将其注册到selector中,状态设置为可读的。
SocketChannel accepted = serverSocketChannel.accept();
accepted.configureBlocking(false);
accepted.register(selector, SelectionKey.OP_READ);
} else if (next.isReadable()) {
//如果可读,就建立读通道。并进行读操作。
SocketChannel channel = (SocketChannel) next.channel();
ByteBuffer tempBuffer = ByteBuffer.allocate(1024);
int length = 0;
while ((length = channel.read(tempBuffer)) > 0) {
tempBuffer.flip();
System.out.println(new String(tempBuffer.array(), 0, length));
tempBuffer.clear();
}
} else if (next.isWritable()) {
//如果可写则进行对应的操作。。。。。。
} else {
//以此类推。。。。。。。。。
}
//重要!!!!!!!处理完selectionkey中的项就将其从selectionKey集合中移除,
// 因为selector不会自动移除selectionkey集合中的项,
// selectionkey集合中的项不被移除会造成重复处理
//selector中有三个集合 keys集合(包含所有注册了的管道信息) selectionkeys集合和CancelledKeys集合
//调用Selector中的select方法后, 会将keys中selector感兴趣的Channel 加入到selectionkeys中
selectionKeyIterator.remove();
}
}
}
}