JAVA实现简单的登陆、群聊、私聊功能

(一)登录

  • 1.定义一个接口来对整个代码进行规范

public interface Chat {
//登录

    String LOGIN_FLAG = "u+";

//私聊

    String PRIVATE_FLAG = "p+";

//群聊

    String PUBLIC_FLAG = "a+";

//分隔符

    String SPLIT_FLAG = "♥";

//成功的状态

String SUCCESS = "1";

//失败状态

    String FAILURE = "-1";
}
  • 2.定义UserManager类 管理所有登录⽤的信息
    public class UserMannager {

    //保存所有用户信息

   private Map users= new HashMap<>();

/**
* 判断用户是否登陆
*/

    public  boolean isLogined(String name){
        //遍历数组
        for (String key:users.keySet()) {
             if(key.equals(name)){
                 return true;
             }
        }
                 return  false;
    }

/**
* 保存当前登录的用户信息
*/

    public void save(String name,Socket socket){
     users.put(name,socket);
    }

/**
* 通过用户名找到对应的socket
*/

    public Socket socketByname(String name){
        return users.get(name);
    }

/**
* 通过socket对象找到对应的名称
*/

    public String nameBySocket(Socket socket){
        for(String key:users.keySet()){
            //取出这个key对应的socket
            if(socket==users.get(key)){
                return key;
            }
        }
        return null;
    }

/**
* 获取所有人的socket对象
*/

    public  synchronized Collection allUsers(){
        return users.values();
    }
}
  • 3.Server类
  • 主线程管理监听客户端的连接

//用于保存每一个用户对应的姓名和Socket

    public static UserMannager mannager  = new UserMannager();
    public static void main(String[] args) {
        try(ServerSocket ss = new ServerSocket(100)) {
            //监听所有来连接的客户端
            while(true){
                Socket socket = ss.accept();
                //让子线程处理一下socket
                new ServerThread(socket).start();
            }
        } catch (IOException e) {

        }
    }
  • ⼦线程处理每个客户端的输⼊输出,判断登录,私聊还是
 private Socket socket;
    public ServerThread(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        BufferedReader br = null;
        PrintStream ps = null;
        try {
            //得到对应的输入流对象
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //得到对应的输出流
            ps = new PrintStream(socket.getOutputStream());

            String line = null;
            while((line=br.readLine())!=null){
                //登陆 u+...u+
                if(line.startsWith(Chat.LOGIN_FLAG)&&line.endsWith(Chat.LOGIN_FLAG)){
                    String name = line.substring(2,line.length()-2);
                    //判断这个用户是否已经登陆
                    if (Server.mannager.isLogined(name)){
                        //登录过了
                        //发送结果给客户端
                        ps.print(Chat.FAILURE);
                    }else{
                        //没有登录
                        //保存当前登录的用户信息
                        Server.mannager.save(name,socket);
                        ps.print(Chat.SUCCESS);
                    }
             }
        } catch (IOException e) {
            e.printStackTrace();
        }
       super.run();
    }
  • 3.Clientr类
  • 主线程:接收终端的输入和服务器的输入,并将从终端获取的数据给服务器
public static void main(String[] args) {
       BufferedReader br = null;
       PrintStream ps = null;
       BufferedReader brServer = null;
       //连接服务器
       try(Socket socket = new Socket("10.129.3.135",100)){
           //登录
           //接受终端输入流
           br = new BufferedReader(new InputStreamReader(System.in));
           //发给服务器端的输出流
           ps = new PrintStream(socket.getOutputStream());
           //接收服务器端的输入流
           brServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
       while(true){
           //接收终端输入信息
           String line = JOptionPane.showInputDialog("请输入用户名");
           //拼接登陆格式
           String loginStr = Chat.LOGIN_FLAG + line + Chat.LOGIN_FLAG;
           //发送给服务器端
           ps.println(loginStr);
           //接收服务器端返回的结果
           String result = brServer.readLine();
           if (result.equals(Chat.SUCCESS)){
               System.out.println("登陆成功");
               break;
           }else {
               System.out.println("用户名已经存在 请重新登录");
           }
       }
       //登陆成功
           //开启线程处理服务器的输入
           new ClientThread(socket).start();
       //接收终端输入 发送给服务器端
           String line;
       while ((line=br.readLine())!=null){
           //发送给服务器
           ps.println(line);
       }
       } catch (IOException e) {
       }
   }
}
  • 子线程:
class ClientThread extends Thread{
    private Socket socket;
    public  ClientThread(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        BufferedReader br = null;
        try {
            br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = null;
            while ((line=br.readLine())!=null){
                //发送给服务器
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("网络出错!");
        }finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (socket != null) {
                    socket.close();
                }

            }catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
}

(二)私聊

判断是否为私聊

 else if (line.startsWith(Chat.PRIVATE_FLAG)&&line.endsWith(Chat.PRIVATE_FLAG)){
                //p+jack♥hellop+

//获取信息

                    String msg = line.substring(2,line.length()-2);

//分割

                    String[] items = msg.split(Chat.SPLIT_FLAG);

//用户名

                    String name = items[0];

//聊天内容

                    String message = items[1];

//通过用户名找到对应的socket

                    Socket desSocket = Server.mannager.socketByname(name);
                    PrintStream desPs = new PrintStream(desSocket.getOutputStream());

//获取当前用户的名称

                    String currentName = Server.mannager.nameBySocket(socket);

//发送私聊消息

                    desPs.println(currentName+"向你发来私聊"+message);

(三)群聊

//剩下的一种便是群聊
处理数据

                    String msg = line.substring(2,line.length()-2);

//获取当前用户的名称

                    String currentName = Server.mannager.nameBySocket(socket);

//遍历所有的用户信息

                    Collection sockets = Server.mannager.allUsers();
                    for (Socket s:sockets) {
                        PrintStream tempps = new PrintStream(s.getOutputStream());
                        tempps.println(currentName+"发来群聊"+msg);

(四)今日小结:

今日做的这个实战有着成功也有着失败,成功的是通过这两天重复这些知识点,我逐渐能够知道实现某个功能需要使用什么办法,能跟上写代码的节奏了。失败的地方是我写了之后发现自己什么东西都显示不出来,自己对照了几次,晚上又写了几遍发现还是不想,始终没有找到问题到底出现在哪里,心里很难受啊

你可能感兴趣的:(JAVA实现简单的登陆、群聊、私聊功能)