使用Java socket 简单实现实时通信,单聊,群聊功能

  1. 一对一单聊的实现:客户端带着发送方ID和接收方ID、信息发送给服务端,服务端从socket池中找出接收方ID进行转发。
  2. 群发的实现:客户端发送群发消息给服务端,然后服务端从socket池中取出所有正在连接的客户端,然后进行转发
import org.junit.Test;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.UUID;

public class socket {

    static java.util.Map<String, Socket> socketMap = new HashMap<>();

    public static void main(String[] args) throws InterruptedException {


        Thread server = new Thread(() -> {

            try {
                ServerSocket serverSocket = new ServerSocket(6666);
                while (true) {
                    Socket socket = serverSocket.accept();
                    serverRead(socket);
                    

                }
            } catch (IOException e) {
                System.out.println("报错了");
                e.printStackTrace();
            }


        });
        server.join();
        server.start();




        mySocket b = clientConServer();
        
        mySocket a =  clientConServer();

        
        try {
            clientSend(a,"你好",b.id);
            Thread.sleep(1000);

            clientSend(b,"你也好",a.id);
            Thread.sleep(1000);
            clientSendAll(a,"大家好");
        } catch (IOException e) {
            e.printStackTrace();
        }
        Thread.sleep(1000);
        disconnect(a);

        Thread.sleep(1000);
        disconnect(b);
        try {
            a.socket.close();
            b.socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    /**
     * 客户端与服务端建立连接   C
     */
    public static mySocket clientConServer() {
            mySocket socket = new mySocket();
            try {
                PrintWriter printWriter = new PrintWriter(socket.socket.getOutputStream());
                printWriter.write("connect\n");
                printWriter.flush();
                printWriter.write(socket.id+"\n");
                printWriter.flush();
                readThread(socket.socket);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return socket;
    }


    /**
     * 服务器监听  S
     */
    public static void serverRead(Socket socket) throws IOException {
        //开启服务器输入监听线程
        SocketInterface socketRead = (Socket socket1) -> {
            Thread thread = new Thread() {
                public Socket socket = socket1;
                String info;

                @Override
                public void run() {
                    try {
                        //获取输入流
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket1.getInputStream()));

                        while ((info = bufferedReader.readLine()) != null) {

                            //如果监听到连接指令:connect,则获取socketId,并将此socket连接保存到静态map中
                            if (info.equals("connect")) {
                                //获取socketId
                                String key = bufferedReader.readLine();
                                //存入在静态Map中
                                socketMap.put(key, socket);
                                //回传给客户端,提示已经建立连接
                                PrintWriter we = new PrintWriter(socket.getOutputStream());
//                                System.out.println(key);
                                we.write("客户端" + key + "连接服务器成功\n");
                                we.flush();
                            }
                            //如果监听到连接指令:send,则获取发送客户端socketId:from,接受客户端socketId:to,发送的消息:message
                            if ("send".equals(info)){
                                //发送客户端socketId
                               String from = bufferedReader.readLine();
                               //接受客户端socketId
                               String to = bufferedReader.readLine();
                               //发送
                               send(from,bufferedReader.readLine(),to);
                            }
                            //如果监听到连接指令:sendAll,则群发消息
                            if ("sendAll".equals(info)){
                                String from = bufferedReader.readLine();
                                String message = bufferedReader.readLine();
                                mass(message,from);
                            }
                            //如果监听到连接指令:disconnect,则断开与某个客户端的连接
                            if ("disconnect".equals(info)){
                                String from = bufferedReader.readLine();
                                info = from;
                                System.out.println(from+"请求断开连接");

                                socketMap.get(from).getOutputStream().close();
                                socketMap.get(from).getInputStream().close();
                                socketMap.get(from).close();
                                
                            }
//                            System.out.println(info);

                        }
                    } catch (SocketException se) {
                        System.out.println(info+"已断开");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread.start();
        };
        socketRead.read(socket);
    }


    /**
     * 客户端接受信息  C
     *
     * @param socket
     */
    public static void readThread(Socket socket) {
        //开启客户端输入监听线程
        SocketInterface socketRead = (Socket socket1) -> {
            Thread thread = new Thread() {
                public Socket socket = socket1;
                public String info = null;

                @Override
                public void run() {
                    try {
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
                        while ((info = bufferedReader.readLine()) != null) {
                            System.out.println(info);
                        }
                    } catch (SocketException se) {
                        System.out.println("socket关闭");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread.start();

        };
        socketRead.read(socket);
    }

    /**
     * 服务器转发群发消息  S
     *
     * @param message
     */
    
    public static void mass(String message, String fromUUID) {
        //遍历所有已连接服务器的socket
        socketMap.forEach((s, socket) -> {
            if (!socket.isClosed()) {
                try {
//                    发送信息
                    PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
                    printWriter.write( s+"收到来自<---"+fromUUID + "的群发消息:" + message + "\n");
                    printWriter.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 客户端发送给客户端  C
     * @param a
     * @param message
     * @param to
     * @throws IOException
     */
    public static void clientSend(mySocket a,String message,String to) throws IOException {
        PrintWriter printWriter = new PrintWriter(a.socket.getOutputStream());
        printWriter.write("send\n");
        printWriter.flush();
        printWriter.write(a.id+"\n");
        printWriter.flush();
        printWriter.write(to+"\n");
        printWriter.flush();
        printWriter.write(message+"\n");
        printWriter.flush();
    }

    /**
     * 客户端群发消息 C
     * 
     * @param a
     * @param message
     * @throws IOException
     */
    public static void clientSendAll(mySocket a,String message) throws IOException {
        PrintWriter printWriter = new PrintWriter(a.socket.getOutputStream());
        printWriter.write("sendAll\n");
        printWriter.flush();
        printWriter.write(a.id+"\n");
        printWriter.flush();
        printWriter.write(message+"\n");
        printWriter.flush();
    }
    /**
     * 服务器转发 S
     * @param from
     * @param message
     * @param to
     * @throws IOException
     */
    
    public static void send(String from,String message,String to) throws IOException {
        //从socket池中获取接受客户端socket,并写入信息
        PrintWriter printWriter  = new PrintWriter(socketMap.get(to).getOutputStream());
        printWriter.write(to+"\n");
        printWriter.flush();
        printWriter.write(from+"发送给-->"+to+":"+message+"\n");
        printWriter.flush();
    }


   

    /**
     *
     * 断开连接  C
     */
    static void disconnect(mySocket mySocket){
        try {
            PrintWriter printWriter = new PrintWriter(mySocket.socket.getOutputStream());
            printWriter.write("disconnect\n");
            printWriter.flush();
            printWriter.write(mySocket.id+"\n");
            printWriter.flush();
            
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

 




}

 

 static class mySocket {
        public String id;
        public Socket socket;

        mySocket() {
            this.id = UUID.randomUUID().toString();
            try {
                this.socket = new Socket("192.168.157.1", 6666);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

 接口类

import java.net.Socket;

public interface SocketInterface {
    /**
     * 开启监听
     */
    void read(Socket socket);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章