JavaSE實(shí)現(xiàn)多人聊天室功能

本文實(shí)例為大家分享了Java SE實(shí)現(xiàn)多人聊天室功能的具體代碼,供大家參考,具體內(nèi)容如下

成都創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比溫泉網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式溫泉網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋溫泉地區(qū)。費(fèi)用合理售后完善,十余年實(shí)體公司更值得信賴。

實(shí)現(xiàn)功能:

1.實(shí)現(xiàn)用戶注冊(cè)上線,下線

2.實(shí)現(xiàn)群聊和私聊功能

3.實(shí)現(xiàn)統(tǒng)計(jì)當(dāng)前在線人數(shù)

實(shí)現(xiàn)思路:

1.首先,要實(shí)現(xiàn)服務(wù)端與客戶端之間的連接

這里是使用套接字建立TCP連接:

(1)服務(wù)器端先實(shí)例化一個(gè)描述服務(wù)器端口號(hào)的ServerSocket對(duì)象

(2)客戶端要?jiǎng)?chuàng)建Socket對(duì)象來(lái)連接指定的服務(wù)器端

(3)服務(wù)器端調(diào)用ServerSocket類的accept()方法來(lái)監(jiān)聽連接到服務(wù)器端的客戶端信息

(4)若服務(wù)器端與客戶端連接成功,雙方將返回一個(gè)Socket對(duì)象,此時(shí)雙方可以進(jìn)行通信

(5)服務(wù)器端與客戶端使用I/O流進(jìn)行連接,服務(wù)端的輸出流連接客戶端的輸入流,客戶端的輸出流連接服務(wù)端的輸入流

(6)使用close()方法關(guān)閉套接字(一定要記得關(guān)閉)

2.因?yàn)槭菗碛幸粋€(gè)服務(wù)端來(lái)實(shí)現(xiàn)多個(gè)客戶端的連接,此處還要解決的是多線程的問題。

每個(gè)客戶端需要兩個(gè)線程,來(lái)分別處理向服務(wù)端發(fā)送消息和向服務(wù)端接收消息

而服務(wù)端,當(dāng)每增加一個(gè)客戶端與服務(wù)端連接,服務(wù)端都要多創(chuàng)建一個(gè)線程來(lái)處理與客戶端的連接

具體代碼:

單線程實(shí)現(xiàn):

客戶端

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
 
/**
 * @author LXY
 * @email 403824215@qq.com
 * @date 2018/7/20 15:46
 */
//客戶端
public class SingleClient {
  public static void main(String[] args) throws IOException {
    //客戶端連接服務(wù)器,返回套接字Socket對(duì)象
    Socket socket = new Socket("127.0.0.1",6666);
    //獲取服務(wù)端的輸出流,向服務(wù)器端輸出內(nèi)容
    PrintStream printStream = new PrintStream(socket.getOutputStream());
    printStream.println("我是客戶端" + socket.getLocalPort());
    //獲取服務(wù)器端的輸入流,讀取服務(wù)器端的內(nèi)容
    Scanner scanner = new Scanner(socket.getInputStream());
    scanner.useDelimiter("\n");
    if(scanner.hasNext())
    {
      System.out.println(scanner.next());
    }
    //關(guān)閉流
    socket.close();
  }
}

服務(wù)端

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
 
/**
 * @author LXY
 * @email 403824215@qq.com
 * @date 2018/7/20 15:34
 */
//服務(wù)端
public class SingleServer {
  public static void main(String[] args) throws IOException {
    //創(chuàng)建服務(wù)器端的ServerSocket對(duì)象,等待客戶端進(jìn)行連接
    ServerSocket serverSocket = new ServerSocket(6666);
    System.out.println("服務(wù)器的端口號(hào)為6666,等待客戶端連接。。。");
    //偵聽并接收服務(wù)器端的連接,返回套接字Socket對(duì)象
    Socket socket = serverSocket.accept();
    //獲取客戶端的輸入流,讀取客戶端的輸入內(nèi)容
    Scanner scanner = new Scanner(socket.getInputStream());
    scanner.useDelimiter("\n");
    if(scanner.hasNext())
    {
      System.out.println("客戶端發(fā)來(lái)消息:" + scanner.next());
    }
    //獲取客戶端的輸出流,向客戶端輸出內(nèi)容
    PrintStream printStream = new PrintStream(socket.getOutputStream());
    printStream.println("客戶端你好,我是服務(wù)器端:" + serverSocket.getLocalPort());
    //關(guān)閉流
    serverSocket.close();
  }
}

多線程實(shí)現(xiàn)

客戶端

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
 
/**
 * @author LXY
 * @email 403824215@qq.com
 * @date 2018/7/20 15:55
 */
//客戶端
 
//客戶端讀取服務(wù)器端信息的線程
class ClientReadServer implements Runnable
{
  private Socket socket;
 
  public ClientReadServer(Socket socket)
  {
    this.socket = socket;
  }
 
  public void run() {
    try {
      Scanner scanner = new Scanner(socket.getInputStream());
      while (scanner.hasNext())
      {
        System.out.println(scanner.next());
      }
      socket.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
 
 
//客戶端向服務(wù)端發(fā)送信息的線程
class ClientSendServer implements Runnable
{
  private Socket socket;
 
  public ClientSendServer(Socket socket)
  {
    this.socket = socket;
  }
 
  public void run() {
    try {
      PrintStream printStream = new PrintStream(socket.getOutputStream());
      Scanner scanner = new Scanner(System.in);
      while (true)
      {
        String msg = null;
        if(scanner.hasNext())
        {
          msg = scanner.next();
          printStream.println(msg);
        }
        if(msg.equals("bye"))
        {
          scanner.close();
          printStream.close();
          break;
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
 
  }
}
 
public class MultiClient {
  public static void main(String[] args) throws IOException {
    Socket socket = new Socket("127.0.0.1",6666);
    Thread read = new Thread(new ClientReadServer(socket));
    Thread send = new Thread(new ClientSendServer(socket));
    read.start();
    send.start();
  }
}

服務(wù)端

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
/**
 * @author LXY
 * @email 403824215@qq.com
 * @date 2018/7/20 16:12
 */
class Server implements Runnable
{
  private static Map<String,Socket> map = new ConcurrentHashMap<String, Socket>();
 
  private Socket socket;
 
  public Server(Socket socket)
  {
    this.socket = socket;
  }
 
  public void run() {
    try {
      Scanner scanner = new Scanner(socket.getInputStream());
      String msg = null;
      while (true)
      {
        if(scanner.hasNextLine())
        {
          msg = scanner.nextLine();
          Pattern pattern = Pattern.compile("\r");
          Matcher matcher = pattern.matcher(msg);
          msg = matcher.replaceAll("");
          //用戶注冊(cè)——格式:userName:用戶名
          if(msg.startsWith("userName:"))
          {
            String userName = msg.split("\\:")[1];
            userRegist(userName,socket);
            continue;
          }
          //群聊——格式:G:群聊信息
          else if(msg.startsWith("G:"))
          {
            firstStep(socket);
            String str = msg.split("\\:")[1];
            groupChat(socket,str);
            continue;
          }
          else if(msg.startsWith("P:") && msg.contains("-"))
          {
            firstStep(socket);
            String userName = msg.split("\\:")[1].split("-")[0];
            String str = msg.split("\\:")[1].split("-")[1];
            privateChat(socket,userName,str);
            continue;
          }
          else if(msg.contains("bye"))
          {
            firstStep(socket);
            userExit(socket);
            continue;
          }
          else
          {
            PrintStream printStream = new PrintStream(socket.getOutputStream());
            printStream.println("格式輸入錯(cuò)誤");
            continue;
 
          }
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
 
  }
 
  private void firstStep(Socket socket) throws IOException {
    Set<Map.Entry<String,Socket>> set = map.entrySet();
    for(Map.Entry<String,Socket> entry:set)
    {
      if(entry.getValue().equals(socket))
      {
        if(entry.getValue() == null)
        {
          PrintStream printStream = new PrintStream(socket.getOutputStream());
          printStream.println("請(qǐng)先進(jìn)行注冊(cè)操作!格式為:[userName:用戶名]");
        }
      }
    }
  }
 
  private void userRegist(String userName, Socket socket) {
    map.put(userName,socket);
    System.out.println("用戶名:" + userName + "客戶端" + socket +"上線了!!");
    System.out.println("當(dāng)前在線人數(shù)為" + map.size() + "人");
  }
 
  private void groupChat(Socket socket, String msg) throws IOException {
    Set<Map.Entry<String,Socket>> set = map.entrySet();
    String userName = null;
    for(Map.Entry<String,Socket> entry:set)
    {
      if(entry.getValue().equals(socket))
      {
        userName = entry.getKey();
        break;
      }
    }
    for(Map.Entry<String,Socket> entry:set)
    {
      Socket client = entry.getValue();
      PrintStream printStream = new PrintStream(client.getOutputStream());
      printStream.println(userName + "說" + msg);
    }
  }
 
  private void privateChat(Socket socket, String userName, String msg) throws IOException {
    String curUser = null;
    Set<Map.Entry<String,Socket>> set = map.entrySet();
    for(Map.Entry<String,Socket> entry:set)
    {
      if(entry.getValue().equals(socket))
      {
        curUser = entry.getKey();
        break;
      }
    }
    Socket client = map.get(userName);
    PrintStream printStream = new PrintStream(client.getOutputStream());
    printStream.println(curUser + "私聊說" + msg);
  }
 
  private void userExit(Socket socket) {
    String userName = null;
    for(String key:map.keySet())
    {
      if(map.get(key).equals(socket))
      {
        userName = key;
        break;
      }
    }
    map.remove(userName,socket);
    System.out.println("用戶" + userName + "已下線");
  }
}
 
 
public class MultiServer {
  public static void main(String[] args) {
    try {
      ServerSocket serverSocket = new ServerSocket(6666);
      //使用線程池
      ExecutorService executorService = Executors.newFixedThreadPool(20);
      for(int i = 0;i < 20;i++)
      {
        System.out.println("歡迎來(lái)到聊天室。。。");
        Socket socket = serverSocket.accept();
        System.out.println("新人加入。。。");
        executorService.execute(new Server(socket));
      }
      executorService.shutdown();
      serverSocket.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
 
  }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

當(dāng)前文章:JavaSE實(shí)現(xiàn)多人聊天室功能
網(wǎng)站網(wǎng)址:http://muchs.cn/article6/ihsjog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)電子商務(wù)、網(wǎng)站策劃、網(wǎng)站改版、軟件開發(fā)、網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)