Javaソケット実装チャットルーム

7634 ワード

クライアント・プログラム:クライアントには2つのスレッドがあります.1つはプライマリ・クラスSocketClientがサーバにメッセージを送信します.1つは内部クラスreadLineThreadがサーバから送信されたメッセージをリスニングします.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class SocketClient extends Socket{

    private static final String SERVER_IP = "127.0.0.1";
    private static final int SERVER_PORT = 2017;
    
    private Socket client;
    private PrintWriter out;
    private BufferedReader in;
    
    /**
     *       ,       
     */
    public SocketClient() throws Exception{
        super(SERVER_IP, SERVER_PORT);
        client = this;
        out = new PrintWriter(this.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(this.getInputStream()));
        new readLineThread();
        
        while(true){
            in = new BufferedReader(new InputStreamReader(System.in));
            String input = in.readLine();
            out.println(input);
        }
    }
    
    /**
     *                    
     */
    class readLineThread extends Thread{
        
        private BufferedReader buff;
        public readLineThread(){
            try {
                buff = new BufferedReader(new InputStreamReader(client.getInputStream()));
                start();
            } catch (Exception e) {
            }
        }
        
        @Override
        public void run() {
            try {
                while(true){
                    String result = buff.readLine();
                    if("byeClient".equals(result)){//       ,         
                        break;
                    }else{//         
                        System.out.println(result);
                    }
                }
                in.close();
                out.close();
                client.close();
            } catch (Exception e) {
            }
        }
    }
    
    public static void main(String[] args) {
        try {
            new SocketClient();//     
        } catch (Exception e) {
        }
    }
}

≪サーバー・プログラム|Server Program|ldap≫:サーバーには3つのクラス・プライマリ・クラス・サーバーがクライアント・リクエストをリスニングし、スレッドが内部クラスPrintOutThreadを処理することを有効にして出力メッセージ・リクエストをリスニングし、すべてのクライアント・内部クラス・サーバーThreadにメッセージを送信して各ユーザーとの接続を提供します.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Server extends ServerSocket {

    private static final int SERVER_PORT = 2017;

    private static boolean isPrint = false;//         
    private static List user_list = new ArrayList();//       
    private static List thread_list = new ArrayList();//           
    private static LinkedList message_list = new LinkedList();//       

    /**
     *      Socket,            ,          
     */
    public Server() throws IOException {
        super(SERVER_PORT);//   ServerSocket
        new PrintOutThread();//             

        try {
            while (true) {//        ,        
                Socket socket = accept();
                new ServerThread(socket);
            }
        } catch (Exception e) {
        } finally {
            close();
        }
    }

    /**
     *               ,        
     */
    class PrintOutThread extends Thread {

        public PrintOutThread() {
            start();
        }

        @Override
        public void run() {
            while (true) {
                //      ,if         ,        isPrint   
                System.out.println("   。。。"+isPrint);
                if (isPrint) {//                     ,       。
                    String message = (String) message_list.getFirst();
                    for (ServerThread thread : thread_list) {
                        thread.sendMessage(message);
                    }
                    message_list.removeFirst();
                    isPrint = message_list.size() > 0 ? true : false;
                }
            }
        }
    }

    /**
     *       
     */
    @SuppressWarnings("unchecked")
    class ServerThread extends Thread {
        private Socket client;
        private PrintWriter out;
        private BufferedReader in;
        private String name;

        public ServerThread(Socket s) throws IOException {
            client = s;
            out = new PrintWriter(client.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(client.getInputStream()));
            //in.readLine();
            out.println("       ,       :");
            start();
        }

        @Override
        public void run() {
            try {
                int flag = 0;
                String line = in.readLine();
                while (true) {
                    //         
                    if ("showuser".equals(line)) {
                        out.println(this.listOnlineUsers());
                    }
                    if("bye".equals(line)){
                        out.println("bye");
                    break;}
                    //      ,    
                    if (flag++ == 0) {
                        name = line;
                        user_list.add(name);
                        thread_list.add(this);
                        out.println(name + "  ,       ...");
                        this.pushMessage("Client     ...");
                    } else {
                        this.pushMessage("Client say : " + line);
                    }
                    line = in.readLine();
                    
                }
                out.println("byeClient");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {//        
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                thread_list.remove(this);
                user_list.remove(name);
                pushMessage("Client      ");
            }
        }

        //         ,        
        private void pushMessage(String msg) {
            message_list.addLast(msg);
            isPrint = true;
        }

        //           
        private void sendMessage(String msg) {
            out.println(msg);
        }

        //         
        private String listOnlineUsers() {
            String s = "---        ---\015\012";
            for (int i = 0; i < user_list.size(); i++) {
                s += "[" + user_list.get(i) + "]\015\012";
            }
            s += "--------------------";
            return s;
        }
    }

    public static void main(String[] args) throws IOException {
        new Server();//      
    }
}

ここでマルチスレッドの問題が発生したようです
@Override
public void run() {
    while (true) {
        //      ,if         ,        isPrint   
        System.out.println("   。。。"+isPrint);
        if (isPrint) {//                     ,       。
            String message = (String) message_list.getFirst();
            for (ServerThread thread : thread_list) {
                thread.sendMessage(message);
            }
            message_list.removeFirst();
            isPrint = message_list.size() > 0 ? true : false;
        }
    }
}

Javaソケットの簡単な例
原文住所:https://vhcffh.com/archives/l