Android_开发_Day19_简单的网络聊天群聊与私聊的编写

Android_开发Day19简单的网络聊天的编写

目的:

将前两节的学的网络和多线程的知识联系起来,来一个综合的训练,提高对知识的运用。

技术:

<1> 网络的相关知识,包括怎么连接,怎么传输数据。
<2> 文件的相关知识,包括字符,字节,音频,视频,图片,以及文件的打开关闭,读取,写入等。
<3> 多线程的相关知识,如何创建一个多线程,开启一个多线程,以及线程安全。
<4> 异常处理的相关知识,如何处理异常,如何抓异常,如何关闭资源。
<5> 集合相关的知识,如何创建一个集合,要创建哪种集合,如何使用一个集合。
<6> 字符相关的知识,如何处理一个字符串,如何判断一个字符串含有什么,如何分割一个字符串,如何取一个字符串的子字符串。

技术如何使用:

public class Communicate {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(8787);
        } catch (IOException e) {
            System.out.println("服务器开启失败!");
        }
        UserManager userManager = new UserManager();
        while (true) {
            Socket socket = null;
            try {
                socket = serverSocket.accept();
            } catch (IOException e) {
                System.out.println("未能被客户端连接!");
            }
            new MyThread(socket, userManager).start();
        }
    }
}
class MyThread extends Thread{
    private Socket socket = null;
    private UserManager userManager = null;

    public MyThread(Socket Socket, UserManager userManager){
        this.socket = Socket;
        this.userManager = userManager;
    }

    @Override
    public void run() {
        String line = null;
        String name = null;
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            while ((line = bufferedReader.readLine()) != null){
                if (line.startsWith("u+") && line.endsWith("u+")){
                    PrintStream printStream = new PrintStream(socket.getOutputStream());
                    name = line.substring(2,line.length()-2);
                    if (userManager.isLogined(name)){
                        printStream.println("服务器:你已登录,无需重复登陆!");
                    } else {
                        userManager.Save(name,socket);
                        printStream.println("服务器:登录成功!");
                        System.out.println(name+"登录");
                    }
                }else if (line.startsWith("@")){
                    String name1 = line.substring(1,line.indexOf(" "));
                    String message = line.substring(line.indexOf(" ")+1);
                    Socket socket1 = userManager.getSocket(name1);
                    PrintStream printStream1 = new PrintStream(socket1.getOutputStream());
                    printStream1.println(name1+":"+message);
                }
                else{
                    for (Socket sockets:userManager.getAllSocket()) {
                        PrintStream printStream1 = new PrintStream(sockets.getOutputStream());
                        if(sockets == socket){
                            printStream1.println(line+":"+name);
                        }else {
                            printStream1.println(name+":"+line);
                        }
                    }
                    System.out.println(name+":"+line);
                }
            }
        } catch (IOException e) {
            System.out.println(name+"已下线");
        }finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

服务器端的的代码,以及登录时需要多个接口,因此用多线程来解决,我在写这个的时候就是遇到了这个问题,想了半天才想通要用多线程,其实道理很简单,就像接待新生入学一样,你是主线程,你只需要接待一个学生然后将学生的安排工作给你的小弟去完成就行了,这样你就可以返回去又接另一个学生,而不是卡在安排学生上,这些让子线程去做就好。

public class HgClientBaiHeZi {
    public static void main(String[] args) {
        String name = JOptionPane.showInputDialog("请输入用户名:");
        Socket socket = null;
        try {
            socket = new Socket("10.129.17.80",8787);
        } catch (IOException e) {
            System.out.println("亲,网络有问题哦!");
        }
        new ThreadBaiHeZi(socket).start();
        try {
            PrintStream printStream = new PrintStream(socket.getOutputStream());
            printStream.println("u+"+name+"u+");
        } catch (IOException e) {
            System.out.println("连接断开了,请稍后重试!");
        }
        Scanner scanner = new Scanner(System.in);
        while (true){
            String line = scanner.nextLine();
            try {
                PrintStream printStream = new PrintStream(socket.getOutputStream());
                printStream.println(line);
            } catch (IOException e) {
                System.out.println("连接断开了,请稍后重试!");
            }
        }

    }
}
class ThreadBaiHeZi extends Thread{
    private Socket socket = null;
    public ThreadBaiHeZi(Socket socket1){
        socket = socket1;
    }

    @Override
    public void run() {
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = null;
            while ((line = bufferedReader.readLine()) != null){
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("网络连接超时,请稍后再试!");
        }finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这是客户端的代码,客户端的话也需要多线程,因为客户端既可以发消息的同时还可以接消息,因此接收消息的过程让子线程去做,发送消息的过程让主线程来做。同样的代码可以多复制几份然后就是多个客户端了,让多个客户端连接上服务器就可以实现群聊和私聊。

public class UserManager {
    private HashMap HgMember = new HashMap<>();
    public boolean isLogined(String name){
        for (String key:HgMember.keySet()) {
            if (key.equals(name)){
                return true;
            }
        }
        return false;
    }
    public void Save(String name, Socket socket){
        HgMember.put(name,socket);
    }
    public Socket getSocket(String key){
        return HgMember.get(key);
    }
    public Collection getAllSocket(){
        return HgMember.values();
    }
}

这是用户管理器,目的是为了管理用户,在发群聊的时候需要将消息传给每一个用户,因此需要一个集合来管理用户,同时也可以判断用户是否登录。

实际使用效果:

Android_开发_Day19_简单的网络聊天群聊与私聊的编写_第1张图片
登录界面.jpg
Android_开发_Day19_简单的网络聊天群聊与私聊的编写_第2张图片
王五与张三私聊了所以他俩有私聊信息的记录.jpg
Android_开发_Day19_简单的网络聊天群聊与私聊的编写_第3张图片
李四没有接收到私聊信息只有群聊信息.jpg
Android_开发_Day19_简单的网络聊天群聊与私聊的编写_第4张图片
客户端既有群聊信息也有私聊信息.jpg
Android_开发_Day19_简单的网络聊天群聊与私聊的编写_第5张图片
服务器端记录了所有人发的信息.jpg

总结:

网络是个有趣的东西,学会网络的使用将给编程带来一些乐趣。

你可能感兴趣的:(Android_开发_Day19_简单的网络聊天群聊与私聊的编写)