JAVA NIO 实现群聊
生活随笔
收集整理的這篇文章主要介紹了
JAVA NIO 实现群聊
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
JAVA NIO 實現群聊
一、群聊服務器
package com.dashu.netty.group_chat;import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.nio.charset.StandardCharsets; import java.util.Iterator;public class GroupChatServer {/*** 初始化選擇器*/private Selector selector;/*** 初始化服務器網絡通道*/private ServerSocketChannel serverSocketChannel;/*** 端口*/private static final int PORT = 6666;/*** 構造方法*/public GroupChatServer() {try {//獲取選擇器selector = Selector.open();//獲取服務器網絡通道serverSocketChannel = ServerSocketChannel.open();//網絡地址InetSocketAddress inetSocketAddress = new InetSocketAddress(PORT);//服務器網絡通道綁定網絡地址serverSocketChannel.socket().bind(inetSocketAddress);//設置服務器網絡通道非阻塞serverSocketChannel.configureBlocking(false);//將服務器網絡通道注冊到選擇器上,綁定連接請求事件serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);} catch (Exception e) {e.printStackTrace();}}/*** 監聽客戶端請求事件*/public void listen() {try {//無限循環while (true) {//獲取請求數int count = selector.select();//count大于0,則代表有請求進來if (count > 0) {//獲取請求集Iterator<SelectionKey> selectionKeyIterator = selector.selectedKeys().iterator();//遍歷請求集while (selectionKeyIterator.hasNext()) {//得到請求SelectionKey selectionKey = selectionKeyIterator.next();//連接請求if (selectionKey.isAcceptable()) {//獲取客戶端網絡通道SocketChannel socketChannel = serverSocketChannel.accept();//設置客戶端網絡通道非阻塞socketChannel.configureBlocking(false);//將客戶端網絡通道注冊到選擇器上socketChannel.register(selector, SelectionKey.OP_READ);System.out.println(socketChannel.getRemoteAddress() + "上線了");}//信息讀取請求if (selectionKey.isReadable()) {//客戶端信息讀取readData(selectionKey);}//移除請求selectionKeyIterator.remove();}} else {System.out.println("等待...");}}} catch (Exception e) {e.printStackTrace();}}/*** 客戶端信息讀取** @param selectionKey*/private void readData(SelectionKey selectionKey) {//初始化客戶端網絡通道SocketChannel socketChannel = null;try {//獲取客戶端網絡通道socketChannel = (SocketChannel) selectionKey.channel();//創建緩沖區ByteBuffer byteBuffer = ByteBuffer.allocate(1024);//讀取客戶端網絡通道中的數據到緩沖區int count = socketChannel.read(byteBuffer);//判斷緩沖區中是否有數據if (count > 0) {//將緩沖區的數據轉換位字符串String message = new String(byteBuffer.array());System.out.println(message.trim());//將信息群發到其他客戶端sendInfoToOtClients(message, socketChannel);}} catch (Exception e) {e.printStackTrace();}}/*** 將信息群發到其他客戶端** @param message* @param socketChannel*/private void sendInfoToOtClients(String message, SocketChannel socketChannel) {//獲取所有注冊到選擇器的客戶端,并遍歷for (SelectionKey selectionKey : selector.keys()) {//獲取通道Channel channel = selectionKey.channel();//判斷通道是否屬于SocketChannel,同時不等于發送信息的客戶端if (channel instanceof SocketChannel && channel != socketChannel) {//通道轉換SocketChannel sc = (SocketChannel) channel;//將信息寫入緩沖區ByteBuffer byteBuffer = ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8));try {//將緩沖區的數據寫入通道sc.write(byteBuffer);} catch (Exception e) {e.printStackTrace();}}}}public static void main(String[] args) {GroupChatServer groupChatServer = new GroupChatServer();System.out.println("服務器啟動,開始監聽客戶端請求...");groupChatServer.listen();}}二、客戶端
package com.dashu.netty.group_chat;import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.nio.charset.StandardCharsets; import java.util.Iterator; import java.util.Scanner;public class GroupChatClient {/*** 網絡連接地址*/private final String HOST = "127.0.0.1";/*** 端口*/private final int PORT = 6666;/*** 初始化選擇器*/private Selector selector;/*** 初始化網絡通道*/private SocketChannel socketChannel;/*** 用戶名*/private String username;public GroupChatClient() {try {//獲取選擇器selector = Selector.open();//獲取服務器網絡地址InetSocketAddress inetSocketAddress = new InetSocketAddress(HOST, PORT);//獲取網絡通道socketChannel = SocketChannel.open(inetSocketAddress);//設置網絡通道非阻塞socketChannel.configureBlocking(false);//將網絡通道注冊到選擇器socketChannel.register(selector, SelectionKey.OP_READ);//獲取用戶名System.out.println("請輸入用戶名:");Scanner scanner = new Scanner(System.in);username = scanner.nextLine();System.out.println(username + " 進入群聊...");} catch (Exception e) {e.printStackTrace();}}/*** 向服務器發送信息** @param message*/public void sendInfo(String message) {message = username + ":" + message;try {//向通道寫入數據socketChannel.write(ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8)));} catch (Exception e) {e.printStackTrace();}}/*** 讀取服務器發來的信息*/public void readInfo() {try {//獲取請求數int count = selector.select();if (count > 0) {//獲取請求集Iterator<SelectionKey> selectionKeyIterator = selector.selectedKeys().iterator();//遍歷請求集while (selectionKeyIterator.hasNext()) {//獲取請求SelectionKey selectionKey = selectionKeyIterator.next();//判斷位讀請求if (selectionKey.isReadable()) {//獲取通道SocketChannel sc = (SocketChannel) selectionKey.channel();//創建緩沖區ByteBuffer byteBuffer = ByteBuffer.allocate(1024);//讀取通道的數據到緩沖區sc.read(byteBuffer);//緩沖區數據轉字符串String message = new String(byteBuffer.array());//輸出System.out.println(message.trim());}//移除已完成請求selectionKeyIterator.remove();}}} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {GroupChatClient groupChatClient = new GroupChatClient();/*** 開啟一個線程,每3秒讀取一次服務器發來的信息*/new Thread() {@Overridepublic void run() {while (true) {groupChatClient.readInfo();try {Thread.sleep(3000);} catch (Exception e) {e.printStackTrace();}}}}.start();//信息輸入Scanner scanner = new Scanner(System.in);System.out.println("請輸入信息:");while (scanner.hasNextLine()) {String s = scanner.nextLine();//信息發送groupChatClient.sendInfo(s);System.out.println("請輸入信息:");}}}三、效果圖
1、服務器
2、客戶端01
3、客戶端02
總結
以上是生活随笔為你收集整理的JAVA NIO 实现群聊的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue可以配合jade以及sass吗_在
- 下一篇: 什么是句柄?指针和句柄的区别