最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

本文實(shí)例為大家分享了java基于NIO實(shí)現(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 注冊(cè)到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()));
     }
     
     }
  
     
    }
    // 刪除當(dāng)前的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);

  // 將該通道 注冊(cè)到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);

     }

     // 移除當(dāng)前的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();
    // 取消注冊(cè)
    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()) {
   // 通過(guò) key 取出對(duì)應(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()進(jìn)行接入 操作的時(shí)候, 獲取通道有兩種方式

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

2、定義一個(gè)全局變量

在進(jìn)行初始化的時(shí)候,存儲(chǔ)(socketChannel = ServerSocketChannel.open();)
建立連接 socketChannel .accept();

key.isReadable() 當(dāng)進(jìn)行到讀入操作的時(shí)候( ) SelectionKey key accept = (SocketChannel) key.channel();

演示

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

客戶端發(fā)送消息

啟動(dòng)第二個(gè)客戶端

兩個(gè)客戶端相互通信

離線信息顯示

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

相關(guān)文章

  • DecimalFormat多種用法詳解

    DecimalFormat多種用法詳解

    這篇文章主要為大家詳細(xì)介紹了DecimalFormat的多種用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Java實(shí)現(xiàn)心跳機(jī)制的方法

    Java實(shí)現(xiàn)心跳機(jī)制的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)心跳機(jī)制的方法,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • jdk21下載、安裝詳細(xì)教程(Windows、Linux、macOS)

    jdk21下載、安裝詳細(xì)教程(Windows、Linux、macOS)

    本文介紹了OpenJDK 21的下載地址和安裝步驟,包括Windows、Linux和macOS平臺(tái),下載后解壓并設(shè)置環(huán)境變量,最后驗(yàn)證安裝,感興趣的朋友一起看看吧
    2025-03-03
  • JAVALambda表達(dá)式與函數(shù)式接口詳解

    JAVALambda表達(dá)式與函數(shù)式接口詳解

    大家好,本篇文章主要講的是JAVALambda表達(dá)式與函數(shù)式接口詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • seata springcloud整合教程與遇到的坑

    seata springcloud整合教程與遇到的坑

    seata 是alibaba 出的一款分布式事務(wù)管理器,他有侵入性小,實(shí)現(xiàn)簡(jiǎn)單等特點(diǎn)。這篇文章主要介紹了seata springcloud整合教程與遇到的坑,需要的朋友可以參考下
    2021-07-07
  • JDK安裝方法和Linux常見設(shè)置詳細(xì)版教程

    JDK安裝方法和Linux常見設(shè)置詳細(xì)版教程

    這篇文章主要給大家介紹了關(guān)于JDK安裝方法和Linux常見設(shè)置的相關(guān)資料,文章詳細(xì)介紹了如何在Linux系統(tǒng)中設(shè)置靜態(tài)IP、用戶名和主機(jī)名,配置防火墻,安裝JDK以及如何創(chuàng)建系統(tǒng)快照,需要的朋友可以參考下
    2024-11-11
  • 手把手教你怎么創(chuàng)建spring項(xiàng)目

    手把手教你怎么創(chuàng)建spring項(xiàng)目

    今天教大家怎么寫spring項(xiàng)目,文中有非常詳細(xì)的圖文示例及介紹,對(duì)正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • 解決Maven多模塊編譯慢的問(wèn)題

    解決Maven多模塊編譯慢的問(wèn)題

    這篇文章主要介紹了Maven多模塊編譯慢的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java線程池的優(yōu)點(diǎn)及池化技術(shù)的應(yīng)用

    Java線程池的優(yōu)點(diǎn)及池化技術(shù)的應(yīng)用

    這篇文章主要介紹了Java線程池的優(yōu)點(diǎn)及池化技術(shù)的應(yīng)用,Java種提高程序的執(zhí)行效率有兩種實(shí)現(xiàn)方法,一個(gè)是使用線程、另一個(gè)是使用線程池,下文我們就來(lái)具體介紹該詳細(xì)內(nèi)容吧,需要的小伙伴可以參考一下
    2022-05-05
  • SpringCloud讀取Nacos配置中心報(bào)錯(cuò)及遇到的坑:Could?not?resolve?placeholder?‘xxx’?in?value?‘${xxx}

    SpringCloud讀取Nacos配置中心報(bào)錯(cuò)及遇到的坑:Could?not?resolve?placehold

    這篇文章主要介紹了SpringCloud讀取Nacos配置中心報(bào)錯(cuò):Could?not?resolve?placeholder?‘xxx’?in?value?‘${xxx},本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03

最新評(píng)論

黄冈市| 古浪县| 新蔡县| 邵阳县| 景泰县| 涞源县| 白山市| 佛学| 抚顺市| 观塘区| 武邑县| 瓮安县| 昭通市| 武胜县| 成安县| 焦作市| 阿尔山市| 醴陵市| 民乐县| 天祝| 西和县| 汉川市| 和林格尔县| 吉隆县| 吕梁市| 翁牛特旗| 长沙市| 玛多县| 乌海市| 台安县| 运城市| 吴忠市| 黔西县| 漾濞| 鸡泽县| 呼图壁县| 商城县| 莫力| 容城县| 山丹县| 大渡口区|