基于网路编程以及多线程的实战项目---------聊天室

目录

一、需求分析

二、业务逻辑以及要构建的类的分析

1.UserLogin类

2.KeHuDuan类

3.ChatServer类

4.ChatThread类

5.LoginServer

6.ReadThread类

7.WriteThread类

8.总结

三、总结

四、注意

 

一、需求分析

1.首先该聊天室是基于网络编程以及多线程的,所以要有客户端与服务器的交互过程,同时应为多线程的加入允许多人登录聊天。

2.其次,聊天室是多人的。所以要实现颧髎和私聊两种聊天模式。

二、业务逻辑以及要构建的类的分析

1.UserLogin类

首先用户需要进行登录,所以我们要创建一个userlogin进行用户信息存储以及用户的登陆验证

代码如下:

public class UserLogin {
    //登陆验证
    public static boolean isLogin(String username, String password){
        Map usermap = is();
        if (usermap.containsKey(username) && password.equals(usermap.get(username))){
            System.out.println("登陆成功!!!");
            return true;
        }else {
            System.out.println("登陆失败!!!");
            return false;
        }
    }
    //存储用户数据
    private static Map is(){
        Map userMap = new HashMap<>();
        userMap.put("小张","123456");
        userMap.put("小王","123456");
        userMap.put("小刘","123456");
        userMap.put("小李","123456");
        return userMap;
    }
}

2.KeHuDuan类

该类主要用于向服务器发出请求,并接收客户端协会的数据

代码如下:

public class KeHuDuan {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost",6667);

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = sc.next();

        System.out.println("请输入密码:");
        String password = sc.next();

        //向服务器发送账号密码
        OutputStream os = socket.getOutputStream();
        PrintWriter pw = new PrintWriter(os);
        pw.println(username+"-"+password);
        pw.flush();

        //接收服务器回写的信息
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String message = br.readLine();

        if (Boolean.valueOf(message)){//如果登陆成功
            chat(username);//开始聊天
        }
    }

    private static void chat(String username) throws IOException {
        //连接聊天服务器
        Socket socket = new Socket("localhost",5874);

        //向服务器发送用户信息
        OutputStream os = socket.getOutputStream();
        PrintWriter pw = new PrintWriter(os);
        pw.println(username);
        pw.flush();
        //开启写线程任务
        new WriteThread(socket).start();
        //开启读线程任务
        new ReadThread(socket).start();
    }
}

3.ChatServer类

该类用来和客户端交互

代码如下:

public class ChatServer {
    static Map socketMap = new HashMap<>();
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(5874);
        while (true){
            System.out.println("聊天服务器已启动,等待客户端连接");
            Socket socket = server.accept();
            System.out.println("连接成功");

            //接收客户端发送的用户信息
            InputStream is  = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String username = br.readLine();
            System.out.println("读取到的用户名:"+username);
            socketMap.put(username,socket);
            //开启聊天线程任务
            new ChatThread(socket).start();
        }
    }
}

4.ChatThread类

该类是本项目的核心类,编写了群聊和私聊的的业务

代码如下:

public class ChatThread extends Thread{
    private Socket socket;
    public ChatThread(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        while (true){
            try {
                InputStream is = socket.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String message = br.readLine();
                System.out.println("读到的内容"+message);
                String[] values = message.split("-");
                Map socketMap = ChatServer.socketMap;
                Set keyset = socketMap.keySet();
                //长度为1是群聊
                if (values.length == 1){
                    for (String username : keyset){
                        Socket socket1 = socketMap.get(username);
                        //向除了自己以外的其他人发送消息
                        if (socket1 != socket){
                            OutputStream os = socket1.getOutputStream();
                            PrintWriter pw = new PrintWriter(os);
                            pw.println(message);
                            pw.flush();
                        }
                    }
                }else {
                    //获取用户名
                    String username = values[0];
                    //私聊
                    //获取对应的客户端通道
                    Socket socket2 = socketMap.get(username);
                    OutputStream os = socket2.getOutputStream();
                    PrintWriter pw = new PrintWriter(os);
                    pw.println(values[1]);
                    pw.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

5.LoginServer

登陆服务器 用于登录

代码如下:

public class LoginServer {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(6667);
        while (true) {
            System.out.println("登录服务器已启动,等待客户端连接");
            Socket socket = server.accept();
            System.out.println("连接成功");

            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String message =  br.readLine();
            System.out.println("message"+message);
            String[] values = message.split("-");//拆分
            String username = values[0];
            String password = values[1];
            System.out.println(username+":"+password);
            boolean flag = UserLogin.isLogin(username,password);
            System.out.println("flag"+flag);

            //回写信息
            OutputStream os = socket.getOutputStream();
            PrintWriter pw = new PrintWriter(os);
            pw.println(flag+"");
            pw.flush();
        }
    }
}

6.ReadThread类

该类用于客户端读操作

代码如下:

public class ReadThread extends Thread{
    private  Socket socket;
    public ReadThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        while (true){
            //读取信息
            try {
                InputStream is = socket.getInputStream();
                BufferedReader br =new BufferedReader( new InputStreamReader(is));
                String message = br.readLine();
                System.out.println("客户端读到的消息"+message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

7.WriteThread类

该类用于客户端写操作

代码如下:

public class WriteThread extends Thread{
    private Socket socket;
    public  WriteThread(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        Scanner sc = new Scanner(System.in);
        while (true){
            //写出消息
            try {
                OutputStream os = socket.getOutputStream();
                PrintWriter pw = new PrintWriter(os);
                System.out.println("请输入聊天内容");
                String message = sc.next();
                pw.println(message);
                pw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

8.总结

首先,用户登录,客户端向登陆服务器发送请求

然后登陆服务器将进行登陆验证,若验证通过向客户端发送登陆成功i信号。

客户端收到登录成功信号后,想聊天服务器发出聊天请求

聊天服务器开启聊天线程

聊天线程进行群聊还是私聊的判定

三、总结

该项目融合了网络编程、多线程、集合、以及转化流等知识点,代码并不难,主要是弄清楚其中的业务逻辑,以及客户端和服务器的交互过程。

四、注意

该项目测试时 直接输入聊天内容判定为群聊

姓名-聊天内容     的格式为私聊

测试时要讲客户端窗口多开  同时登陆多个用户方可看到效果

你可能感兴趣的:(java,ide)