1.不同于BIO实现的多人聊天软件(使用多线程的方式实现),NIO使用了IO多路复用选择器实现一个服务端就能为多个客户端实现连接;
服务端
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
public class NioServer2 {
public static void main(String[] args) throws IOException {
//创建一个客服务端
ServerSocketChannel server = ServerSocketChannel.open();
//绑定至一个端口
server.bind(new InetSocketAddress(6667));
//配置channel为非阻塞状态
server.configureBlocking(false);
//创建一个IO多路复用选择器
Selector selector = Selector.open();
//绑定服务端至选择器
server.register(selector, SelectionKey.OP_ACCEPT);
while (true){
//使用select调用select方法进行系统调用
int select = selector.select();
//上面的方法如果没有配置超时时间的话,那么就会阻塞
//拿到所有发生文件变化事件的集合
Set<SelectionKey> selectionKeys = selector.selectedKeys();
//使用迭代器去遍历,并且使用这种方式处理想要关注的事件
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()){
SelectionKey accept_item = iterator.next();
//处理完成之后删除
iterator.remove();
if (accept_item.isAcceptable()){
//一旦有连接过来连接我,就执行accept方法,进行三次握手
SocketChannel accept = server.accept();
accept.configureBlocking(false);
//相比较之前的地方需要使用ByteBuffer进行文件的传输
accept.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1000));
}
if (accept_item.isReadable()){
//item是可读的,那么就使用他获取对应的channel,使用channel进行数据的输入输出
SocketChannel channel = (SocketChannel) accept_item.channel();
//通过这个方法获取到之前连接时的一个ByteBuffer,需要强制转换
ByteBuffer buffer = (ByteBuffer) accept_item.attachment();
//清空之前缓存的数据
buffer.clear();
channel.read(buffer);
//int lenth = 0;
//lenth = buffer.limit() - buffer.position();
//int start = buffer.limit() - lenth;
//显示内容
System.out.println(new String(buffer.array(),0,buffer.position()));
}
}
}
}
}
客户端
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Scanner;
public class NioClient2 {
public static void main(String[] args) throws IOException {
SocketChannel client = SocketChannel.open();
client.configureBlocking(false);
client.connect(new InetSocketAddress(6667));
if (client.finishConnect()) {//调用此函数保证客户端成功的连接至服务端
while (true) {
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
//包装起来直接发送
client.write(ByteBuffer.wrap(next.getBytes()));
}
}
}
}