NIO网络编程应用实例——群聊系统
生活随笔
收集整理的這篇文章主要介紹了
NIO网络编程应用实例——群聊系统
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
GroupChatServer.java
package com.atguigu.nio.groupchat;import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator;public class GroupChatServer {//定義屬性private Selector selector;private ServerSocketChannel listenChannel;private static final int PORT = 6667;//構造器//初始化工作public GroupChatServer() {try {//得到選擇器selector = Selector.open();//ServerSocketChannellistenChannel = ServerSocketChannel.open();//綁定端口listenChannel.socket().bind(new InetSocketAddress(PORT));//設置非阻塞模式listenChannel.configureBlocking(false);//將該listenChannel 注冊到selectorlistenChannel.register(selector, SelectionKey.OP_ACCEPT);}catch (IOException e) {e.printStackTrace();}}//監聽public void listen() {System.out.println("監聽線程: " + Thread.currentThread().getName());try {//循環處理while (true) {int count = selector.select();if(count > 0) {//有事件處理//遍歷得到selectionKey 集合Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {//取出selectionkeySelectionKey key = iterator.next();//監聽到acceptif(key.isAcceptable()) {SocketChannel sc = listenChannel.accept();sc.configureBlocking(false);//將該 sc 注冊到seletorsc.register(selector, SelectionKey.OP_READ);//提示System.out.println(sc.getRemoteAddress() + " 上線 ");}if(key.isReadable()) { //通道發送read事件,即通道是可讀的狀態//處理讀 (專門寫方法..)readData(key);}//當前的key 刪除,防止重復處理iterator.remove();}} else {System.out.println("等待....");}}}catch (Exception e) {e.printStackTrace();}finally {//發生異常處理....}}//讀取客戶端消息private void readData(SelectionKey key) {//取到關聯的channelSocketChannel channel = null;try {//得到channelchannel = (SocketChannel) key.channel();//創建bufferByteBuffer buffer = ByteBuffer.allocate(1024);int count = channel.read(buffer);//根據count的值做處理if(count > 0) {//把緩存區的數據轉成字符串String msg = new String(buffer.array());//輸出該消息System.out.println("form 客戶端: " + msg);//向其它的客戶端轉發消息(去掉自己), 專門寫一個方法來處理sendInfoToOtherClients(msg, channel);}}catch (IOException e) {try {System.out.println(channel.getRemoteAddress() + " 離線了..");//取消注冊key.cancel();//關閉通道channel.close();}catch (IOException e2) {e2.printStackTrace();;}}}//轉發消息給其它客戶(通道)private void sendInfoToOtherClients(String msg, SocketChannel self ) throws IOException{System.out.println("服務器轉發消息中...");System.out.println("服務器轉發數據給客戶端線程: " + Thread.currentThread().getName());//遍歷 所有注冊到selector 上的 SocketChannel,并排除 selffor(SelectionKey key: selector.keys()) {//通過 key 取出對應的 SocketChannelChannel targetChannel = key.channel();//排除自己if(targetChannel instanceof SocketChannel && targetChannel != self) {//轉型SocketChannel dest = (SocketChannel)targetChannel;//將msg 存儲到bufferByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());//將buffer 的數據寫入 通道dest.write(buffer);}}}public static void main(String[] args) {//創建服務器對象GroupChatServer groupChatServer = new GroupChatServer();groupChatServer.listen();} }GroupChatClient.java
package com.atguigu.nio.groupchat;import java.io.IOException; 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.util.Iterator; import java.util.Scanner; import java.util.Set;public class GroupChatClient {//定義相關的屬性private final String HOST = "127.0.0.1"; // 服務器的ipprivate final int PORT = 6667; //服務器端口private Selector selector;private SocketChannel socketChannel;private String username;//構造器, 完成初始化工作public GroupChatClient() throws IOException {selector = Selector.open();//連接服務器socketChannel = socketChannel.open(new InetSocketAddress("127.0.0.1", PORT));//設置非阻塞socketChannel.configureBlocking(false);//將channel 注冊到selectorsocketChannel.register(selector, SelectionKey.OP_READ);//得到usernameusername = socketChannel.getLocalAddress().toString().substring(1);System.out.println(username + " is ok...");}//向服務器發送消息public void sendInfo(String info) {info = username + " 說:" + info;try {socketChannel.write(ByteBuffer.wrap(info.getBytes()));}catch (IOException e) {e.printStackTrace();}}//讀取從服務器端回復的消息public void readInfo() {try {int readChannels = selector.select();if(readChannels > 0) {//有可以用的通道Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();if(key.isReadable()) {//得到相關的通道SocketChannel sc = (SocketChannel) key.channel();//得到一個BufferByteBuffer buffer = ByteBuffer.allocate(1024);//讀取sc.read(buffer);//把讀到的緩沖區的數據轉成字符串String msg = new String(buffer.array());System.out.println(msg.trim());}}iterator.remove(); //刪除當前的selectionKey, 防止重復操作} else {//System.out.println("沒有可以用的通道...");}}catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) throws Exception {//啟動我們客戶端GroupChatClient chatClient = new GroupChatClient();//啟動一個線程, 每個3秒,讀取從服務器發送數據new Thread() {public void run() {while (true) {chatClient.readInfo();try {Thread.currentThread().sleep(3000);}catch (InterruptedException e) {e.printStackTrace();}}}}.start();//發送數據給服務器端Scanner scanner = new Scanner(System.in);while (scanner.hasNextLine()) {String s = scanner.nextLine();chatClient.sendInfo(s);}}}總結
以上是生活随笔為你收集整理的NIO网络编程应用实例——群聊系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Scattering:将数据写入到buf
- 下一篇: mysql的优化——索引介绍