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