JAVA-day13

8339 ワード

一、目的
Socketによるチャットとチャット機能の実現
二、機能と使用規範
  • 1.クライアントごとの名前
  • 2.あるクライアントにチャットを開始する
  • 3.グループチャットクライアントはサーバー側にファイルを送信するか、文字サーバー側はクライアントからのデータしか得られない.クライアントとサーバー側はクライアントの需要を規範化しなければならない.送信文字の中で
  • を体現することができる.
  • 1.ログインU+名前U+
  • 2.結果成功1失敗-1
  • を返します.
  • 3.チャットP+名前:チャット内容P+
  • 4.チャットグループa+チャット内容a+
  • 5.ファイルf+
  • 6.音声v+
  • 三、具体的な実現
    1.仕様の定義
    public interface ChatProtocol {
        //  
        String LOGIN_FLAG="u+";
        //  
        String PRIVATE_FLAG="p+";
        //  
        String PUBLIC_FLAG="a+";
    
        //   
        String SPLIT_FLAG="♥";
    
        //     
        String SUCCESS="1";
        String FALURE="-1";
    }
    

    2.UserManagerクラスの定義
    すべてのログインを管理するユーザMapは、あるユーザが既にログインしているか否かを判断する
    (1)保存するユーザ情報
    public Map users = new HashMap<>();
    

    (2)ユーザが既にログインしているか否かを判断する
    public synchronized boolean isLogined(String name) {
            //    
            for (String key : users.keySet()) {
                if (key.equals(name)) {
                    return true;
                }
            }
            return false;
        }
    

    (3)現在ログインしているユーザ情報の保存
    public synchronized void sava(String name, Socket socket) {
            users.put(name, socket);
        }
    

    (4)ユーザ名で対応するsocketを見つける
    public synchronized Socket socketByName(String name) {
            return users.get(name);
        }
    

    (5)socketオブジェクトから対応する名前を見つける
    public synchronized String nameBySocket(Socket socket) {
            for (String key : users.keySet()) {
                //    key   socket
                if (socket == users.get(key)) {
                    return key;
                }
            }
            return null;
        }
    

    (6)全員のsocketオブジェクトを取得する
    public synchronized Collection allUsers(){
            return users.values();
        }
    

    3.サーバクラスのシミュレーションサーバ側の定義
    (1)ホストスレッド管理傍受クライアントの接続
    public class Server {
        //               socket
        public static UserManager manager=new UserManager();
    
                    public static void main(String[] args) {
                        //  ServerSocket
                        try (ServerSocket ss = new ServerSocket(8888)) {
                            //           
                            while (true){
                                Socket socket=ss.accept();
    
                                //        socket
                    new ServerThread(socket).start();
    
                }
            }catch (IOException e){
    
            }
        }
    }
    

    (2)サブスレッド処理クライアント毎の入出力
    class ServerThread extends Thread{
        public 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());
    

    (3)ログインか否かの判断
    String line=null;
                while ((line=br.readLine())!=null){
                    //   u+....u+
                    if (line.startsWith(ChatProtocol.LOGIN_FLAG)&&line.endsWith(ChatProtocol.LOGIN_FLAG)){
                        //u+jacku+
                        String name=line.substring(2,line.length()-2);
    
                        //            
                        if (Server.manager.isLogined(name)){
                            //    
                            //        
                            ps.println(ChatProtocol.FALURE);
                        }else{
                            //    
                            //           
                            System.out.println(name+"   ");
                            Server.manager.sava(name,socket);
                            //        
                            ps.println(ChatProtocol.SUCCESS);
                        }
                    }
    

    (4)雑談
    //       
                    else if (line.startsWith(ChatProtocol.PRIVATE_FLAG)&&line.endsWith(ChatProtocol.PRIVATE_FLAG)){
                        //p+jack♥hellop+
                        //    
                        String msg=line.substring(2,line.length()-2);
                        //   jack hello
                        String[] items=msg.split(ChatProtocol.SPLIT_FLAG);
                        //   
                        String name=items[0];
                        //    
                        String message=items[1];
                        //         socket
                        Socket desSocket=Server.manager.socketByName(name);
                        PrintStream desPs=new PrintStream(desSocket.getOutputStream());
    
                        //         
                        String currentName=Server.manager.nameBySocket(socket);
    
                        //      
                        desPs.println(currentName+"      :"+message);
                    }
    

    (5)グループチャット
    else {
                        //  
                        //
                        String msg=line.substring(2,line.length()-2);
                        //         
                        String currentName=Server.manager.nameBySocket(socket);
    
                        //        
                        Collection sockets=Server.manager.allUsers();
                        for (Socket s:sockets){
                            PrintStream tempps=new PrintStream(s.getOutputStream());
                            tempps.println(currentName+":"+msg);
                            //tempps.close();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    4.Clientクラスシミュレーションクライアントの定義
    (1)メインスレッド
    public class Client {
        public static void main(String[] args) {
            BufferedReader br=null;
            PrintStream ps=null;
            BufferedReader brServer=null;
            //     
            try (Socket socket = new Socket("10.129.11.163", 9300)) {
                //  
                //       
                br=new BufferedReader(new InputStreamReader(System.in));
                //         
                ps=new PrintStream(socket.getOutputStream());
                //          
                brServer=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                while (true){
                    //        
                    //BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
                    //String line=br.readLine();
                    String line=JOptionPane.showInputDialog("      ");
                    //      
                    String loginStr=ChatProtocol.LOGIN_FLAG+line+ChatProtocol.LOGIN_FLAG;
                    //       
                    ps.println(loginStr);
                    //           
                    String result=brServer.readLine();
    
                    //      
                    if (result.equals(ChatProtocol.SUCCESS)){
                        System.out.println(line+"    ");
                        break;
                    }else{
                        System.out.println("            ");
                    }
                }
                //    
                //             
                new ClientThread(socket).start();
    
                //              
                String line=null;
                while ((line=br.readLine())!=null){
                    //      
                    ps.println(line);
                }
    
            }catch (IOException e){
    
            }
        }
    }
    

    (2)サブスレッド
    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){
    
                }
            }
        }
    }