溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時間:2022-09-05 10:00:06 來源:億速云 閱讀:154 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下怎么用Java Socket實(shí)現(xiàn)聊天室功能的相關(guān)知識點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

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)啟動");
            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)啟動");
            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)榭赡苡卸鄠€Client與ChatServer進(jìn)行交互,所以一旦有Client連接成功就新創(chuàng)建一個線程與之交互
                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ù)端地址,端口號
        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("請輸入用戶名");
            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ā)消息不一定是與同一個人,所以創(chuàng)建兩個線程分別用于收和發(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)識符,判斷是群聊還是單聊
                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這個Client發(fā)送"hello"
                Scanner scanner = new Scanner(System.in);
                System.out.println("請輸入聊天內(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);
            }
        }
    }
}

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

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

8 測試

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

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

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

8.1 登錄

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

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

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

8.2 群聊

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

8.3 單聊

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

以上就是“怎么用Java Socket實(shí)現(xiàn)聊天室功能”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI