NIO实现通信聊天:
服务端步骤:
1.创建NI0通道,并且绑定端口
2.开启非阻塞模式
3.创建Selector选择器,并将通道注册到选择器上边,设置关系事件---》新链接
4.循环监听通道的事件
5.监听到新连接事件
5.1:建立和客户端连接的通道
5.2:通道设置为非阻塞
5.3:通道设置完成,将关系事件设置为读取
6.监听到读取事件
6.1:获取客户端通道
6.2:将通道的数据写入到缓冲区(buffer)当中
6.3:打印数据
服务器端:
public class Server {
public static void main(String[] args) throws IOException {
// 获取一个ServerSocket通道
ServerSocketChannel serverChannel = ServerSocketChannel.open();
// serverChannel通道一直监听4700端口
serverChannel.socket().bind(new InetSocketAddress(4700));
// 设置serverChannel为非阻塞
serverChannel.configureBlocking(false);
//创建Selector选择器用来监听通道
Selector selector = Selector.open();
// 把ServerSocketChannel注册到selector中,并且selector对客户端的连接操作感兴趣
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服务启动成功!");
while (true) {
/*
* 如果事件没有到达 selector.select() 会一直阻塞等待
*/
selector.select();
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isAcceptable()) // 如果是OP_ACCEPT事件,则进行连接获取和事件注册
{
ServerSocketChannel server = (ServerSocketChannel) key.channel(); //连接获取
SocketChannel socketChannel = server.accept(); // 获取通道
socketChannel.configureBlocking(false); // 设置为非阻塞
socketChannel.register(selector, SelectionKey.OP_READ); //这里只注册了读事件,如果需要给客户端写数据,则需要注册写事件
System.out.println("客户端连接成功!");
} else if (key.isReadable()) //如果是OP_READ事件,则进行读取和打印
{
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(128);//创建Buffer
int len = socketChannel.read(byteBuffer);
if (len > 0) //如果有数据,则打印数据
{
System.out.println("接受到客户端数据" + new String(byteBuffer.array()));
}
}
// 从事件集合中删除本次处理的key,防止下次select重复处理
iterator.remove();
}
}
}
}
客户端:
public class Client {
public static void main(String[] args) throws IOException {
//打开channel通道
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false); //设置为非阻塞
InetSocketAddress address = new InetSocketAddress("101.43.152.120",4700);
while (!socketChannel.connect(address)){
while (!socketChannel.finishConnect()){
System.out.println("连接中,客户端可以进行其他工作");
}
// Scanner scanner = new Scanner(System.in);
// String str = scanner.next();
Scanner scanner=new Scanner(System.in);
do {
String str=scanner.next();
ByteBuffer aa = ByteBuffer.wrap(str.getBytes()); // 将数据转换成字节信息写入到Buffer当中
socketChannel.write(aa); //将Buffer当中的数据写入channel
} while (!scanner.equals("bye"));
scanner.close();
System.in.read();
}
}
}