欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java基于NIO實現(xiàn)群聊模式

 更新時間:2021年11月23日 17:11:49   作者:林夕$相心  
這篇文章主要為大家詳細介紹了java實現(xiàn)NIO實現(xiàn)群聊模式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了java基于NIO實現(xiàn)群聊模式的具體代碼,供大家參考,具體內(nèi)容如下

Client

package com.qst.chat;

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;

public class GroupChatClient {
 private final int PORT = 9999;
 private final String HOST = "localhost";
 private SocketChannel channel;
 private static Selector selector;

 private String name;
 
 public GroupChatClient() throws IOException {

  selector = Selector.open();
  // 連接服務(wù)器
  channel = SocketChannel.open(new InetSocketAddress(HOST, PORT));
  // 設(shè)置非阻塞
  channel.configureBlocking(false);
  // 將channel 注冊到selector
  channel.register(selector, SelectionKey.OP_READ);
   name = channel.getLocalAddress().toString().substring(1);

  System.out.println(name + "is ok ....");

 }
 // 向服務(wù)器發(fā)送消息
 public void sendTO(String msg) {
  
  ByteBuffer buffer = ByteBuffer.wrap((name+":"+msg).getBytes());
  try {
   channel.write(buffer);
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }
 // 讀取從服務(wù)器端回復(fù)的消息
 public static void getInfo() {
  
  try {
   if(selector.select() >0) {
    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
    
    while(iterator.hasNext()) {
     SelectionKey key = iterator.next();
     
     if(key.isReadable()) {
     // 得到通道
     SocketChannel sc =  (SocketChannel) key.channel();
     
     ByteBuffer buffer = ByteBuffer.allocate(1024);
     
     int len;
     
     // 把讀到的緩沖區(qū)的數(shù)據(jù)轉(zhuǎn)成字符串
     while((len = sc.read(buffer)) > 0) {
      System.out.println(new String(buffer.array()));
     }
     
     }
  
     
    }
    // 刪除當前的selectionKey, 防止重復(fù)操作
    iterator.remove();
    
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
 }
 
 public static void main(String[] args) {
  try {
   GroupChatClient client = new GroupChatClient();
   
   
   new Thread() {
    
    
    public void run() {
     while(true)
     {
      try {
       Thread.sleep(3000);
       GroupChatClient.getInfo();
      } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     }
     
    };
   }.start();
   
   
   Scanner sc = new Scanner(System.in);
//   while(true) {
//    String name = sc.nextLine();
//    client.sendTO(name);
//   }
   while(sc.hasNextLine()) {
      String s = sc.nextLine();
              client.sendTO(s);
   }
   
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

}

Server端

package com.qst.chat;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.time.chrono.IsoChronology;
import java.util.Iterator;

import com.sun.accessibility.internal.resources.accessibility;

import sun.print.resources.serviceui;

public class GroupChatServer {

 private static ServerSocketChannel socketChannel;
 private static Socket socket;
 private static Selector selector;
 private static SocketChannel accept;

 public GroupChatServer() throws IOException {

  socketChannel = ServerSocketChannel.open();

  selector = Selector.open();
  // 綁定端口
  socketChannel.socket().bind(new InetSocketAddress(9999));
  // 設(shè)置非阻塞模式
  socketChannel.configureBlocking(false);

  // 將該通道 注冊到selector
  socketChannel.register(selector, SelectionKey.OP_ACCEPT);

 }

 // 監(jiān)聽
 public static void listen() {
  System.out.println("監(jiān)聽線程: " + Thread.currentThread().getName());
  try {
   while (selector.select() > 0) {

    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();

    if (iterator.hasNext()) {
     // 遍歷得到selectionKey 集合
     SelectionKey next = iterator.next();
     if (next.isAcceptable()) {
      next.channel();
      // socketChannel = (ServerSocketChannel) next.channel();
      SocketChannel accept = socketChannel.accept();
      accept.configureBlocking(false);

      accept.register(selector, SelectionKey.OP_READ);

       System.out.println(accept.getRemoteAddress()+" 上線 了。。。");
     }
     if (next.isReadable()) {
      readDate(next);

     }

     // 移除當前的next,防止重復(fù)處理
     iterator.remove();
     // System.out.println("未發(fā)現(xiàn)");

    }

   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }

 // 讀取客戶端消息
 public static void readDate(SelectionKey key) {

  try {
   accept = (SocketChannel) key.channel();
   ByteBuffer buffer = ByteBuffer.allocate(1024);
   int len = accept.read(buffer);
   if (len > 0) {
    buffer.flip();
    String msg = new String(buffer.array());
    System.out.println("user = " + msg);

    // 向其它的客戶端轉(zhuǎn)發(fā)消息(去掉自己)
    sendToAll(msg, accept);
    buffer.clear();
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   try {
    String msg = accept.getRemoteAddress().toString();
    // 取消注冊
    key.cancel();
    // 關(guān)閉通道
    accept.close();
    System.out.println(msg + "離線了");
   } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
   }
   // e.printStackTrace();
  } finally {
   // TODO: handle finally clause
  }
 }

 public static void sendToAll(String msg, SocketChannel ssc) {
  for (SelectionKey ss : selector.keys()) {
   // 通過 key 取出對應(yīng)的 SocketChannel
   SelectableChannel channel = ss.channel();

   // 排除自己
   if (channel instanceof SocketChannel && channel != ssc) {
    // 轉(zhuǎn)型
    SocketChannel sh = (SocketChannel) channel;
    // 轉(zhuǎn)存到buffer
    ByteBuffer wrap = ByteBuffer.wrap(msg.getBytes());
    try {
     // 寫入通道
     sh.write(wrap);
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }
 }

 public static void main(String[] args) throws IOException {
  GroupChatServer server = new GroupChatServer();
  GroupChatServer.listen();

 }

}

key.isAcceptable()進行接入 操作的時候, 獲取通道有兩種方式

1、 通過selector獲取 (Selector key) socketChannel = (ServerSocketChannel) key.channel();
建立連接 socketChannel .accept();

2、定義一個全局變量

在進行初始化的時候,存儲(socketChannel = ServerSocketChannel.open();)
建立連接 socketChannel .accept();

key.isReadable() 當進行到讀入操作的時候( ) SelectionKey key accept = (SocketChannel) key.channel();

演示

服務(wù)器啟動,客戶端啟動

客戶端發(fā)送消息

啟動第二個客戶端

兩個客戶端相互通信

離線信息顯示

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java使用substring()截取(提取)子字符串

    Java使用substring()截取(提取)子字符串

    這篇文章主要介紹了Java使用substring()截取(提取)子字符串,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • JAVA實現(xiàn)Date日期加一天具體方法

    JAVA實現(xiàn)Date日期加一天具體方法

    這篇文章主要給大家介紹了關(guān)于JAVA實現(xiàn)Date日期加一天的相關(guān)資料,因為在項目中遇到了需要將日期進行加減一些天數(shù)的操作,文中給出了簡單的代碼示例,需要的朋友可以參考下
    2023-07-07
  • SpringBoot四大神器之Actuator的使用小結(jié)

    SpringBoot四大神器之Actuator的使用小結(jié)

    這篇文章主要介紹了SpringBoot四大神器之Actuator的使用小結(jié),詳細的介紹了Actuator的使用和端點的使用,有興趣的可以了解一下
    2017-11-11
  • Java雜談之重復(fù)代碼是什么

    Java雜談之重復(fù)代碼是什么

    剛開始工作時,總有人開玩笑說,編程實際上就是 CV,調(diào)侃很多程序員寫程序依靠的是復(fù)制粘貼。至今,很多初級甚至高級程序員寫代碼依舊是CV,就是把其他項目里的一段代碼復(fù)制過來,稍加改動,然后,跑一下沒有大問題就完事。這就是在給其他人挖坑
    2021-09-09
  • Kafka?日志存儲實現(xiàn)過程

    Kafka?日志存儲實現(xiàn)過程

    這篇文章主要為大家介紹了Kafka?日志存儲的實現(xiàn)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • 詳解Spring中singleton?bean如何同時服務(wù)多個請求

    詳解Spring中singleton?bean如何同時服務(wù)多個請求

    這篇文章主要介紹了詳解Spring中singleton?bean如何同時服務(wù)多個請求
    2023-02-02
  • Springboot整合實現(xiàn)郵件發(fā)送的原理詳解

    Springboot整合實現(xiàn)郵件發(fā)送的原理詳解

    SpringBoot集成郵件服務(wù)非常簡單,通過簡單的學(xué)習(xí)即可快速掌握郵件業(yè)務(wù)類的核心邏輯和企業(yè)郵件的日常服務(wù),本文給大家分享Springboot整合實現(xiàn)郵件發(fā)送的原理,一起看看吧
    2021-06-06
  • Java手機號碼工具類示例詳解(判斷運營商、獲取歸屬地)

    Java手機號碼工具類示例詳解(判斷運營商、獲取歸屬地)

    這篇文章主要介紹了Java手機號碼工具類示例詳解,通過手機號碼來判斷運營商獲取歸屬地,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • 詳解Java去除json數(shù)據(jù)中的null空值問題

    詳解Java去除json數(shù)據(jù)中的null空值問題

    這篇文章主要介紹了詳解Java去除json數(shù)據(jù)中的null空值問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • SpringBoot+Redis執(zhí)行l(wèi)ua腳本的方法步驟

    SpringBoot+Redis執(zhí)行l(wèi)ua腳本的方法步驟

    這篇文章主要介紹了SpringBoot+Redis執(zhí)行l(wèi)ua腳本的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11

最新評論