チャットルームサービス


前言
これは私がjavaで書いたAndroidチャットルームプロジェクトのサービス端で、もちろんjavaプロジェクトにも使えます.ここには2つのサービス端が書かれていて、1つは複数の人のチャットしか実現していません.1つは複数の人で、1対1です.
Androidクライアントソース
  • サービス1(複数人チャット)
  • import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.HashMap;
    
    public class Run2 {
        private final static int PORT = 12345;		//      
        public static ArrayList<Socket> list ;
        public static void main(String[] args) throws IOException {
        	//           
            new Thread(new startServer()).start();
        }
        static class startServer implements Runnable{
            @Override
            public void run() {
                try {
                    ServerSocket server = new ServerSocket(PORT);
            		
                    list = new ArrayList<>();
                    while (true) {
                        Socket client = server.accept();
                        System.out.println(client);
                        //            Socket   List   
                        list.add(client);
                        //            
                        //     ,         Socket,             
                        //      List  ,               
                        new choicesend2(client,list).start();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    class choicesend2 extends Thread {
        private Socket socket;
        private DataOutputStream dos; 
        private DataInputStream dis;
        public ArrayList<Socket> list;
        public choicesend2(Socket socket, ArrayList<Socket> list) {
            this.socket = socket;
            this.list = list;
        }
        @Override
        public void run() {
            try {
            //
                dis = new DataInputStream(socket.getInputStream());
                //         ,          
                while (true) {//        
                
                //                ,     
                    String title;
                    String name;
                    String ip;
                    char[] temp = new char[200];
                    int len = 0;
                    char c = 0;
                    while ((c = dis.readChar()) != '\t') {
                        temp[len] = c;
                        len++;
                    }
                    title = new String(temp, 0, len);
                    len = 0;
                    while ((c = dis.readChar()) != '\t') {
                        temp[len] = c;
                        len++;
                    }
                    name = new String(temp, 0, len);
                    len = 0;
                    while ((c = dis.readChar()) != '\t') {
                        temp[len] = c;
                        len++;
                    }
                    ip = new String(temp, 0, len);
                    System.out.println(ip);
                    
                    //    ,        Socket,       
                    for (Socket socket : list) {
                        if(socket==this.socket)         //        
                            continue;
                         //  dos     Socket,       
                        dos = new DataOutputStream(socket.getOutputStream());
                        try {
                            dos.writeChars(title);
                            dos.writeChar('\t');
                            dos.writeChars(name);
                            dos.writeChar('\t');
                            dos.writeInt(0);
                            dos.flush();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    
    
  • サービス端末2(複数チャット+1対1)
  • 質問:私たちは複数のチャットでArrayListの集合で各接続上のSocketオブジェクトを格納していますが、明らかに私がデータを転送するSocketだと判断できません.
    解決策:ArrayListをHashMapに変更し、キーはユーザーを識別する情報を格納し、値はSocketを格納し、送信時にキーによってその時のSocketと接続するかどうかを判断する
    例えば私のキー転送のipは、ipに基づいて接続が確立されているかどうかを判断します(明らかに1台のコンピュータで相互に転送できません(HashMapは重複していません))
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.HashMap;
    
    public class Run {
        private final static int PORT = 12345;
        public static ArrayList<Socket> list ;
        public static HashMap<String,Socket> hs;
        public static void main(String[] args) throws IOException {
            new Thread(new startServer()).start();
        }
        static class startServer implements Runnable{
            @Override
            public void run() {
                try {
                    ServerSocket server = new ServerSocket(PORT);
                    hs = new HashMap<>();
                    while (true) {
                        Socket client = server.accept();
                        System.out.println(client);
                        hs.put(client.getInetAddress().toString(),client);
                        new choicesend(client,hs).start();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    class choicesend extends Thread {
        private Socket socket;
        private String key;
        private DataOutputStream dos;
        private DataInputStream dis;
        public HashMap<String,Socket> hs;
        public choicesend(Socket socket, HashMap<String,Socket> hs) {
            this.socket = socket;
            this.hs = hs;
        }
        @Override
        public void run() {
            try {
                dis = new DataInputStream(socket.getInputStream());
                while (true) {//        
                    String title;
                    String name;
                    //       ip, HashMap    
                    String ip;		
                    char[] temp = new char[200];
                    int len = 0;
                    char c = 0;
                    while ((c = dis.readChar()) != '\t') {
                        temp[len] = c;
                        len++;
                    }
                    title = new String(temp, 0, len);
                    len = 0;
                    while ((c = dis.readChar()) != '\t') {
                        temp[len] = c;
                        len++;
                    }
                    name = new String(temp, 0, len);
                    len = 0;
                    while ((c = dis.readChar()) != '\t') {
                        temp[len] = c;
                        len++;
                    }
                    ip = new String(temp, 0, len);
                    System.out.println(ip);
                    //      255.255.255.255     
                    if(ip.equals("255.255.255.255")){
                        for(String sendip : hs.keySet()){
                            System.out.println(sendip+"    ip");
                            Socket socket = hs.get(sendip);
                            dos = new DataOutputStream(socket.getOutputStream());
                            try {
                               // System.out.println("   ");
                                dos.writeChars(title);
                                dos.writeChar('\t');
                                dos.writeChars(name);
                                dos.writeChar('\t');
                                dos.writeInt(0);
                                dos.flush();
                            } catch (IOException e) {
                                //list.remove(socket);
                                e.printStackTrace();
                            }
                        }
                    }
                    //      ip HashMap    
                    else{
                        for(String sendip : hs.keySet()){
                           // System.out.println(sendip+"    ip");
                           //    client.getInetAddress().toString()   ip   “/”,       
                            sendip = sendip.substring(1,sendip.length());
                            //          Socket  
                            if(ip.equals(sendip)){
                                Socket socket = hs.get(sendip);
                                if(socket!=null)
                                    dos = new DataOutputStream(socket.getOutputStream());
                                try {
                                    System.out.println("   ");
                                    dos.writeChars(title);
                                    dos.writeChar('\t');
                                    dos.writeChars(name);
                                    dos.writeChar('\t');
                                    dos.writeInt(1);
                                    dos.flush();
                                } catch (IOException e) {
                                   // list.remove(socket);
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
    
    
                }
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    
    

    反省:
    このような一対一の限界は明らかに大きく、ipでマッチングするしかないが、idで人を探したいならどうやってマッチングするのだろうか.登録ログインインタフェースを書くことができると思います.ログイン時にユーザーのSocketを取得することができ、HashMapでメンテナンスし、キーでidを入力し、値はSocketオブジェクトに入力します.このようにログインしている限り、私たちのHashMapに転送され、1対の一時が必要であればidでチャットにマッチすることができます.