作业:利用NIO中的非阻塞式IO的模式,实现一个简易的聊天室,但是服务端能知道当前有多少人在线
package com.rj.bd.zuoye03.zuoye02;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Scanner;
/**
*
-
@desc 利用NIO中的非阻塞式IO的模式,实现一个简易的聊天室,但是服务端能知道当前有多少人在线
-
@author psh
-
@time 2018-11-7
*/
public class NIONotBlockingClient {
public static void main(String[] args) throws Exception {
//1.获取通道
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(“10.2.32.11”,1234));//2.切换成非阻塞模式 socketChannel.configureBlocking(false); //3.开辟指定大小的缓冲区 ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //4.发送数据 Scanner cin = new Scanner(System.in); while (true) { System.out.println("客户端01请输入:"); String inputStr = cin.next(); byteBuffer.put(("我是客户端01:"+inputStr).getBytes()); byteBuffer.flip(); socketChannel.write(byteBuffer); byteBuffer.clear(); }
}
}
package com.rj.bd.zuoye03.zuoye02;
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.Iterator;
/**
*
-
@desc 利用NIO中的非阻塞式IO的模式,实现一个简易的聊天室,但是服务端能知道当前有多少人在线
-
@author psh
-
@time 2018-11-7
*/
public class NIONotBlockingServer {
public static void main(String[] args) throws Exception {
//1.获取通道
System.out.println(“服务端启动。。。。。”);
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//2.切换成非阻塞模式
serverSocketChannel.configureBlocking(false);
//3.绑定连接
serverSocketChannel.bind(new InetSocketAddress(8888));
//4.获取选择器
Selector selector = Selector.open();
//5.将通道注册到选择器上(第二个选项参数叫做选择键,可以用于告诉选择器需要监控这个通道的什么状态或者说做什么事情(读、写、连接、接受))
//选择键是正兴致,如果需要监控钙通道的多个状态或事情,可以将多个选择键用位运算符“或”“|”来连接
//这里服务器首先要监听客户端的接受状态
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
int a = 0;
//6、轮询式地获取选择器上已经“准备就绪”的事情
while (selector.select()>0)
{
//获取当前选择器中所有注册的“选择键(已就绪的监听事件)”
Iterator iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) { //获取“准备”就绪的是事件 SelectionKey selectionKey = iterator.next(); //判断是什么事件准备就绪 if (selectionKey.isAcceptable()) { //10.若接受就绪,获取客户端连接 SocketChannel socketChanner = serverSocketChannel.accept(); System.out.println(socketChanner.getRemoteAddress()+":连接成功了"); a++; //11.客户端连接socketChannel也需要切换非阻塞模式 socketChanner.configureBlocking(false); //12.将改动到注册到选择器上,监控客户端sockdetChannel的读就绪事件 socketChanner.register(selector, SelectionKey.OP_READ); System.out.println("现在连接的人数为:"+a); } else if (selectionKey.isReadable()) { //13.获取当前选择器上“读就绪”状态的通道 SocketChannel socketChanner = (SocketChannel) selectionKey.channel(); //14.设定一个缓冲区 ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //15.取出数据 int len = 0; while ((len=socketChanner.read(byteBuffer))>0) { byteBuffer.flip(); System.out.println(new String(byteBuffer.array(),0,len)); byteBuffer.clear(); } } iterator.remove(); } }
}
}