服务器端
(1)创建server
(2)channel绑定端口号
(3)将channel设置为非阻塞状态
(4)创建Selector
(5)将channel注册到Selector中,选择accept状态
(6)Selector轮询channel,从channel集合中获取有用的channel
(7)selectionKey如果是接收状态,调用方法
(8)selectionKey如果是读状态,调用方法
public void server() throws IOException {
//创建channel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//channel绑定
serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", 8080));
//channel设置为非阻塞状态
serverSocketChannel.configureBlocking(false);
//创建Selector
Selector selector = Selector.open();
//将channel注册到Selector中
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服务器已经启动");
//循环channel
for (; ;) {
int readChannels = selector.select();
if (readChannels == 0) {
continue;
}
//获取可用的channel
Set<SelectionKey> selectionKeys = selector.selectedKeys();
//遍历集合
Iterator<SelectionKey> selectionKeyIterator = selectionKeys.iterator();
while (selectionKeyIterator.hasNext()) {
SelectionKey selectionKey = selectionKeyIterator.next();
if (selectionKey.isAcceptable()) {
// 调用接收方法
acceptOperation(selector, serverSocketChannel);
}else if (selectionKey.isReadable()) {
// 调用读方法
readOperation(selector, selectionKey);
}
selectionKeyIterator.remove();
}
}
}
接收状态方法:
private void acceptOperation(Selector selector, ServerSocketChannel serverSocketChannel) throws IOException {
//获取连接
SocketChannel accept = serverSocketChannel.accept();
//切换非阻塞模式
accept.configureBlocking(false);
//注册到读模式
accept.register(selector, SelectionKey.OP_READ);
//发送提示消息
accept.write(Charset.forName("UTF-8").encode("欢迎进入聊天室"));
}
public static void main(String[] args) throws IOException {
new chatServer().server();
}
读状态方法:
private void readOperation(Selector selector, SelectionKey selectionKey) throws IOException {
// 从SelectionKey中获取已经就绪的通道
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
//创建buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
//循环读取客户端的信息
int read = socketChannel.read(buffer);
String message = "";
if (read > 0) {
//切换读写模式
buffer.flip();
//编码信息
message += Charset.forName("UTF-8").decode(buffer);
}
socketChannel.register(selector, SelectionKey.OP_READ);
//广播消息message
if (message.length() > 0) {
System.out.println(message);
castOtherMessage(message, selector, socketChannel);
}
}
客户端:
public void startClient() throws IOException {
//创建客户端channel
SocketChannel channel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8080));
//输入文本
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
String nextLine = sc.nextLine();
if (nextLine.length() > 0) {
//执行写操作
channel.write(Charset.forName("UTF-8").encode(nextLine));
}
}
}