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

Java?Socket實(shí)現(xiàn)聊天室功能

 更新時(shí)間:2022年09月02日 16:24:43   作者:dreaming9420  
這篇文章主要為大家詳細(xì)介紹了Java?Socket實(shí)現(xiàn)聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

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

1 創(chuàng)建登錄判斷類UserLogin

import java.util.HashSet;
import java.util.Set;

public class UserLogin {

? ? public static boolean login(String username) {
? ? ? ? Set<String> set = initUser();
? ? ? ? // set中含有該username則登錄成功
? ? ? ? return set.contains(username);
? ? }

? ? public static Set<String> initUser() {
? ? ? ? Set<String> set = new HashSet<>();
? ? ? ? set.add("111");
? ? ? ? set.add("222");
? ? ? ? set.add("333");
? ? ? ? set.add("444");
? ? ? ? set.add("555");
? ? ? ? return set;
? ? }
}

2 創(chuàng)建登錄服務(wù)器LoginServer

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class LoginServer {
? ? public static void main(String[] args) {
? ? ? ? int port = 6666;
? ? ? ? try (ServerSocket serverSocket = new ServerSocket(port)) {
? ? ? ? ? ? System.out.println("登錄服務(wù)器已經(jīng)啟動(dòng)");
? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? Socket socket = serverSocket.accept();
? ? ? ? ? ? ? ? // 接收Client輸出的信息(username)
? ? ? ? ? ? ? ? InputStream inputStream = socket.getInputStream();
? ? ? ? ? ? ? ? BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
? ? ? ? ? ? ? ? String username = bufferedReader.readLine();
? ? ? ? ? ? ? ? // 調(diào)用登錄方法,判斷是否成功登錄
? ? ? ? ? ? ? ? OutputStream outputStream = socket.getOutputStream();
? ? ? ? ? ? ? ? PrintStream printStream = new PrintStream(outputStream);
? ? ? ? ? ? ? ? if (UserLogin.login(username)) {
? ? ? ? ? ? ? ? ? ? System.out.println(username + "登錄成功");
? ? ? ? ? ? ? ? ? ? // 登錄成功輸出"true"到Client
? ? ? ? ? ? ? ? ? ? printStream.println("true");
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? System.out.println(username + "登錄失敗");
? ? ? ? ? ? ? ? ? ? // 登錄失敗則輸出"false"到Client
? ? ? ? ? ? ? ? ? ? printStream.println("false");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? printStream.flush();
? ? ? ? ? ? }
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}

3 創(chuàng)建聊天服務(wù)器ChatServer

import com.socket.socketChatroom.bio.thread.ChatThread;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class ChatServer {
? ? // 保存當(dāng)前聊天中的所有Map<username,Socket>
? ? public static Map<String, Socket> socketMap = new HashMap<>();

? ? public static void main(String[] args) {
? ? ? ? int port = 9999;
? ? ? ? try (ServerSocket serverSocket = new ServerSocket(port)) {
? ? ? ? ? ? System.out.println("聊天服務(wù)器已經(jīng)啟動(dòng)");
? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? Socket socket = serverSocket.accept();
? ? ? ? ? ? ? ? // 接收Client輸出的username
? ? ? ? ? ? ? ? InputStream inputStream = socket.getInputStream();
? ? ? ? ? ? ? ? BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
? ? ? ? ? ? ? ? String username = bufferedReader.readLine();
? ? ? ? ? ? ? ? System.out.println(username + "連接到聊天服務(wù)器");
? ? ? ? ? ? ? ? // 連接聊天服務(wù)器成功則將它的<username,Socket>放入socketMap中
? ? ? ? ? ? ? ? socketMap.put(username, socket);
? ? ? ? ? ? ? ? System.out.println(socketMap);
? ? ? ? ? ? ? ? // 因?yàn)榭赡苡卸鄠€(gè)Client與ChatServer進(jìn)行交互,所以一旦有Client連接成功就新創(chuàng)建一個(gè)線程與之交互
? ? ? ? ? ? ? ? new ChatThread(username,socket).start();
? ? ? ? ? ? }

? ? ? ? } catch (IOException e) {
? ? ? ? ? ? throw new RuntimeException(e);
? ? ? ? }
? ? }
}

4 創(chuàng)建客戶端Client

import com.socket.socketChatroom.bio.thread.ReadThread;
import com.socket.socketChatroom.bio.thread.WriteThread;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Client {
? ? public static void main(String[] args) {
? ? ? ? // 服務(wù)端地址,端口號(hào)
? ? ? ? String ip = "127.0.0.1";// 本機(jī)IP地址
? ? ? ? int port = 6666; // 必須和LoginServer的端口一樣
? ? ? ? try {
? ? ? ? ? ? Socket client = new Socket(ip, port);
? ? ? ? ? ? Scanner scanner = new Scanner(System.in);
? ? ? ? ? ? System.out.println("請(qǐng)輸入用戶名");
? ? ? ? ? ? String username = scanner.nextLine();
? ? ? ? ? ? // 將用戶名輸出到LoginServer
? ? ? ? ? ? OutputStream outputStream = client.getOutputStream();
? ? ? ? ? ? PrintStream printStream = new PrintStream(outputStream);
? ? ? ? ? ? printStream.println(username);
? ? ? ? ? ? printStream.flush();
? ? ? ? ? ? // 接收LoginServer輸出的是否登錄成功標(biāo)志("true"或"false")
? ? ? ? ? ? InputStream inputStream = client.getInputStream();
? ? ? ? ? ? BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
? ? ? ? ? ? String state = bufferedReader.readLine();
? ? ? ? ? ? // 如果為"true",則為登錄成功,可以開始聊天
? ? ? ? ? ? if (Boolean.parseBoolean(state)) {
? ? ? ? ? ? ? ? chat(username);
? ? ? ? ? ? }
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }

? ? public static void chat(String username) {
? ? ? ? try {
? ? ? ? ? ? String ip = "127.0.0.1";// 本機(jī)IP地址
? ? ? ? ? ? int port = 9999;// 必須和ChatServer的端口一樣
? ? ? ? ? ? // 連接聊天服務(wù)器ChatServer
? ? ? ? ? ? Socket socket = new Socket(ip, port);
? ? ? ? ? ? // 將username輸出到ChatServer
? ? ? ? ? ? OutputStream outputStream = socket.getOutputStream();
? ? ? ? ? ? PrintStream printStream = new PrintStream(outputStream);
? ? ? ? ? ? printStream.println(username);
? ? ? ? ? ? printStream.flush();
? ? ? ? ? ? // 因?yàn)榱奶斓氖瞻l(fā)消息不一定是與同一個(gè)人,所以創(chuàng)建兩個(gè)線程分別用于收和發(fā)
? ? ? ? ? ? new ReadThread(socket).start();
? ? ? ? ? ? new WriteThread(socket).start();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? throw new RuntimeException(e);
? ? ? ? }
? ? }
}

5 創(chuàng)建服務(wù)器用于處理聊天的線程類ChatThread

import com.socket.socketChatroom.bio.server.ChatServer;

import java.io.*;
import java.net.Socket;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class ChatThread extends Thread {
? ? private final String username;
? ? private final Socket socket;

? ? public ChatThread(String username, Socket socket) {
? ? ? ? this.username = username;
? ? ? ? this.socket = socket;
? ? }

? ? @Override
? ? public void run() {
? ? ? ? while (true) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? // 接收Client的WriteThread線程輸出的消息
? ? ? ? ? ? ? ? InputStream inputStream = socket.getInputStream();
? ? ? ? ? ? ? ? BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
? ? ? ? ? ? ? ? String message = bufferedReader.readLine();
? ? ? ? ? ? ? ? System.out.println(username + "說: " + message);
? ? ? ? ? ? ? ? // 將當(dāng)前所有在線的Client的username存入usernameSet中
? ? ? ? ? ? ? ? Map<String, Socket> socketMap = ChatServer.socketMap;
? ? ? ? ? ? ? ? Set<String> usernameSet = new HashSet<>();
? ? ? ? ? ? ? ? for (Map.Entry<String, Socket> map : socketMap.entrySet()) {
? ? ? ? ? ? ? ? ? ? usernameSet.add(map.getKey());
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 以"-"作為標(biāo)識(shí)符,判斷是群聊還是單聊
? ? ? ? ? ? ? ? String[] values = message.split("-");
? ? ? ? ? ? ? ? if (values.length == 2 && usernameSet.contains(values[0])) { //單聊
? ? ? ? ? ? ? ? ? ? // values[0]為要指定發(fā)送的Client的username
? ? ? ? ? ? ? ? ? ? OutputStream outputStream = socketMap.get(values[0]).getOutputStream();
? ? ? ? ? ? ? ? ? ? PrintStream printStream = new PrintStream(outputStream);
? ? ? ? ? ? ? ? ? ? // values[1]為消息內(nèi)容
? ? ? ? ? ? ? ? ? ? printStream.println(username + "說: " + values[1]);
? ? ? ? ? ? ? ? ? ? printStream.flush();
? ? ? ? ? ? ? ? } else {//群聊
? ? ? ? ? ? ? ? ? ? // 將消息發(fā)送到除自己之外的所有Client
? ? ? ? ? ? ? ? ? ? for (String username : usernameSet) {
? ? ? ? ? ? ? ? ? ? ? ? if (socket != socketMap.get(username)) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? OutputStream outputStream = socketMap.get(username).getOutputStream();
? ? ? ? ? ? ? ? ? ? ? ? ? ? PrintStream printStream = new PrintStream(outputStream);
? ? ? ? ? ? ? ? ? ? ? ? ? ? printStream.println(this.username + "說: " + message);
? ? ? ? ? ? ? ? ? ? ? ? ? ? printStream.flush();
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? throw new RuntimeException(e);
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

6 創(chuàng)建客戶端Client用于發(fā)送消息的線程類WriteThread

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class WriteThread extends Thread {
? ? private final Socket socket;

? ? public WriteThread(Socket socket) {
? ? ? ? this.socket = socket;
? ? }

? ? @Override
? ? public void run() {
? ? ? ? while (true) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? // 獲取輸出流
? ? ? ? ? ? ? ? OutputStream outputStream = socket.getOutputStream();
? ? ? ? ? ? ? ? PrintStream printStream = new PrintStream(outputStream);
? ? ? ? ? ? ? ? // 鍵盤輸入要發(fā)送的消息,若為單聊,則以要發(fā)送的Client的username+"-",開頭,比如"111-hello",表示向111這個(gè)Client發(fā)送"hello"
? ? ? ? ? ? ? ? Scanner scanner = new Scanner(System.in);
? ? ? ? ? ? ? ? System.out.println("請(qǐng)輸入聊天內(nèi)容: ");
? ? ? ? ? ? ? ? String message = scanner.nextLine();
? ? ? ? ? ? ? ? // 輸出消息到ChatServer
? ? ? ? ? ? ? ? printStream.println(message);
? ? ? ? ? ? ? ? printStream.flush();
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? throw new RuntimeException(e);
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

7 創(chuàng)建客戶端Client用于接收消息的線程類ReadThread

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class ReadThread extends Thread {
? ? private final Socket socket;

? ? public ReadThread(Socket socket) {
? ? ? ? this.socket = socket;
? ? }

? ? @Override
? ? public void run() {
? ? ? ? while (true) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? // 從ChatServer獲取消息
? ? ? ? ? ? ? ? InputStream inputStream = socket.getInputStream();
? ? ? ? ? ? ? ? BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
? ? ? ? ? ? ? ? String message = bufferedReader.readLine();
? ? ? ? ? ? ? ? System.out.println(message);
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? throw new RuntimeException(e);
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

項(xiàng)目結(jié)構(gòu)如下圖

8 測(cè)試

先運(yùn)行LoginServer和ChatServer,再運(yùn)行多個(gè)Client
設(shè)置IDEA允許運(yùn)行多個(gè)實(shí)例

8.1 登錄

8.2 群聊

8.3 單聊

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

相關(guān)文章

  • Java實(shí)現(xiàn)并查集示例詳解

    Java實(shí)現(xiàn)并查集示例詳解

    這篇文章主要通過一個(gè)題目示例為大家詳細(xì)介紹Java如何實(shí)現(xiàn)并查集,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • java并發(fā)編程之原子性、可見性、有序性

    java并發(fā)編程之原子性、可見性、有序性

    這篇文章主要給大家分享的是java并發(fā)編程的原子性、可見性和有序性,文章會(huì)具體舉例說明,感興趣的小伙伴可以參考一下文章的具體內(nèi)容
    2021-09-09
  • 關(guān)于Java的Character類詳解

    關(guān)于Java的Character類詳解

    這篇文章主要介紹了關(guān)于Java的Character類詳解,Java中的Character類是一個(gè)包裝類,用于封裝一個(gè)基本數(shù)據(jù)類型char的值,它提供了一些靜態(tài)方法來操作字符,需要的朋友可以參考下
    2023-05-05
  • java服務(wù)器的簡(jiǎn)單實(shí)現(xiàn)過程記錄

    java服務(wù)器的簡(jiǎn)單實(shí)現(xiàn)過程記錄

    在線瀏覽網(wǎng)頁離不開服務(wù)器,用戶發(fā)出請(qǐng)求request,服務(wù)器做出響應(yīng)response,提供給用戶需要的頁面,這篇文章主要給大家介紹了關(guān)于java服務(wù)器簡(jiǎn)單實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 深入Java分布式計(jì)算的使用分析

    深入Java分布式計(jì)算的使用分析

    本篇文章對(duì)Java分布式計(jì)算的使用進(jìn)行了詳細(xì)的介紹。需要的朋友參考下
    2013-05-05
  • Windows10安裝IDEA 2020.1.2的方法步驟

    Windows10安裝IDEA 2020.1.2的方法步驟

    這篇文章主要介紹了Windows10安裝IDEA 2020.1.2的方法步驟,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java實(shí)現(xiàn)的文本字符串操作工具類實(shí)例【數(shù)據(jù)替換,加密解密操作】

    Java實(shí)現(xiàn)的文本字符串操作工具類實(shí)例【數(shù)據(jù)替換,加密解密操作】

    這篇文章主要介紹了Java實(shí)現(xiàn)的文本字符串操作工具類,可實(shí)現(xiàn)數(shù)據(jù)替換、加密解密等操作,涉及java字符串遍歷、編碼轉(zhuǎn)換、替換等相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • java json不生成null或者空字符串屬性(詳解)

    java json不生成null或者空字符串屬性(詳解)

    下面小編就為大家?guī)硪黄猨ava json不生成null或者空字符串屬性(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • 詳解Mybatis 傳遞參數(shù)類型為L(zhǎng)ist的取值問題

    詳解Mybatis 傳遞參數(shù)類型為L(zhǎng)ist的取值問題

    這篇文章主要介紹了詳解Mybatis 傳遞參數(shù)類型為L(zhǎng)ist的取值問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • springboot整合redis修改分區(qū)的操作流程

    springboot整合redis修改分區(qū)的操作流程

    這篇文章主要介紹了springboot整合redis修改分區(qū)的操作流程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評(píng)論

广灵县| 鹰潭市| 南陵县| 华池县| 汶川县| 凯里市| 陵水| 津市市| 杭锦后旗| 启东市| 甘南县| 玉门市| 红河县| 玉山县| 沐川县| 石景山区| 石河子市| 普格县| 西吉县| 射洪县| 锡林郭勒盟| 石景山区| 灌南县| 砀山县| 隆德县| 武安市| 方山县| 广州市| 基隆市| 体育| 温州市| 涟水县| 密云县| 宜春市| 望奎县| 资兴市| 乃东县| 元朗区| 南江县| 平邑县| 嘉禾县|