java single server - multi client socket 통신에서 모든 클라이언트에게 말을 뿌리기.

조회수 5305회

안녕하세요.
자바로 채팅을 만들고 있습니다. 지금까지 작성한 코드는 한 서버에 여러 클라이언트가 접속은 하지만 한 명이 작성한 말을 다른 사람에게 보여주진 않습니다. 클라이언트쪽에서 while문이 도는 조건이 키보드에서 받으면 서버에 전송하고 다시 받아온다는 것인데 여러명에게 뿌리고 클라이언트가 또 그것을 받으려면 제가 키보드로 작성하지 않아도 서버에서 받아오는 역할을 하는 while문이 따로 존재해야 하는 것 같습니다. 그래서 클라이언트에서 두개의 스레드를 작성해보기도 했는데 뭔가 잘 돌아가지 않아서 현재 돌아가는 코드로 다시 복구시켜놓고 질문을 올립니다... 인터넷에 있는 예제들은 gui와 함께 구현돼서 버튼 액션 리스너가 전송 역할을 하고 그 이외에는 한 개 스레드에서 계속 받는 것만 기다리는 while문을 돌리던데 gui를 사용하지 않고 지금 현재 저 코드에서 채팅이 이뤄지도록 하려면 어떻게 해야할지 알고싶습니다. 감사합니다.

Server.java

package Socket;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server {
    static List<ConnectionToClient> clients = new ArrayList<>();

    public static void main(String[] args) {
        try {
            ServerSocket server = new ServerSocket(5000);
            Socket socket = null;
            while ((socket = server.accept()) != null) {
                new ServerThread(socket).start();
            }
            server.close();
        } catch (Exception e) {
        }
    }

    static class ServerThread extends Thread {
        Socket socket;
        ConnectionToClient conToClient;
        ServerThread(Socket socket) {
            this.socket = socket;
             conToClient = new ConnectionToClient(socket);
             clients.add(conToClient); 
        }
        public void run() {
            try {
                String input = "";
                while( (input = conToClient.read())!=null){
                    System.out.println(input);
                    conToClient.write(input);
                }
            } catch (Exception e) {
            }
        }

        public void sendToAll(String message){
            for(ConnectionToClient client :clients){
                client.write(message);
            }
        }
    }

    static class ConnectionToClient {
        Socket socket;
        BufferedReader br;
        ObjectOutputStream oos;

        ConnectionToClient(Socket socket) {
            this.socket = socket;
            try {
                br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                oos = new ObjectOutputStream(socket.getOutputStream());

            } catch (Exception e) {
            }
        }
        public String read(){
            try{
                return br.readLine();
            }catch(Exception e){return null;}
        }
        public void write(Object obj) {
            try {
                oos.writeObject(obj);
                oos.flush();
            } catch (Exception e) {
            }
        }
    }
}

Client.java

package Socket;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {

        try {
            Socket socket = new Socket("127.0.0.1", 5000);
            ConnectionToServer server = new ConnectionToServer(socket);
            System.out.println("[INFO] connet complete");
            messageHandler mHandler = new messageHandler(server);
            mHandler.start();

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

    static class messageHandler extends Thread {
        ConnectionToServer server;

        messageHandler(ConnectionToServer server) {
            this.server = server;
        }

        public void run() {
            try {
                BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));

                String initialLocation = "1 2";
                String input = "";
                String response = "";

                server.write(initialLocation);
                if ((response = server.read()) != null) {
                    drawMap(response);
                }

                while (true) {

                    input = keyboard.readLine();
                    if (input.equals("QUIT")) {
                        break;
                    }

                    server.write(input);
                    response = server.read();
                    drawMap(response);
                }
            } catch (Exception e) {
            }
        }
    }

    static class ConnectionToServer {
        Socket socket;
        BufferedReader br;
        ObjectInputStream ois;
        PrintWriter pw;

        ConnectionToServer(Socket socket) {
            this.socket = socket;
            try {
                br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                pw = new PrintWriter(socket.getOutputStream());
                ois = new ObjectInputStream(socket.getInputStream());
            } catch (Exception e) {
            }
        }

        public void write(String obj) {
            pw.println(obj);
            pw.flush();
        }

        public String read() {
            try {
                return (String) ois.readObject();
            } catch (Exception e) {
                return null;
            }
        }
    }

    public static void drawMap(String command) {
        try {
            String[] yAndX = command.split(" ");
            int y = Integer.parseInt(yAndX[0]);
            int x = Integer.parseInt(yAndX[1]);
            String toPrint = "";
            for (int i = 0; i < 3; i++) {
                toPrint = "";
                for (int j = 0; j < 3; j++) {
                    if (y == i && x == j) {
                        toPrint += "* ";
                        continue;
                    }
                    toPrint += ". ";
                }
                System.out.println(toPrint);
            }
        } catch (Exception e) {
        }
    }
}

1 답변

  • messageHandler thread에서 socket read를 처리하고 main 에서 socket write를 처리하는 해보면 어떨까합니다.

    Server.java

    package Socket;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.ObjectOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Server {
        static List<ConnectionToClient> clients = new ArrayList<>();
    
        public static void main(String[] args) {
            try {
                ServerSocket server = new ServerSocket(5000);
                Socket socket = null;
                while ((socket = server.accept()) != null) {
                    new ServerThread(socket).start();
                }
                server.close();
            } catch (Exception e) {
            }
        }
    
        static class ServerThread extends Thread {
            Socket socket;
            ConnectionToClient conToClient;
            ServerThread(Socket socket) {
                this.socket = socket;
                 this.conToClient = new ConnectionToClient(socket);
                 clients.add(conToClient);
            }
            public void run() {
                try {
                    String input = "";
                    while( (input = conToClient.read())!=null){
                        System.out.println(input);
                        //conToClient.write(input);
                        sendToAll(input);
                    }
                } catch (Exception e) {
                }
            }
    
            public void sendToAll(String message){
                for(ConnectionToClient client :clients){
                    System.out.println("message: " + message);
                    client.write(message);
                }
            }
        }
    
        static class ConnectionToClient {
            Socket socket;
            BufferedReader br;
            ObjectOutputStream oos;
    
            ConnectionToClient(Socket socket) {
                this.socket = socket;
                try {
                    br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    oos = new ObjectOutputStream(socket.getOutputStream());
    
                } catch (Exception e) {
                   System.out.println(e);
                }
            }
            public String read(){
                try{
                    return br.readLine();
                }catch(Exception e){
                    System.out.println(e);
                    return null;
                }
            }
            public void write(Object obj) {
                try {
                    oos.writeObject(obj);
                    oos.flush();
                } catch (Exception e) {
                   System.out.println(e);
                }
            }
        }
    }
    

    Client.java

    package Socket;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.ObjectInputStream;
    import java.io.PrintWriter;
    import java.net.Socket;
    
    public class Client {
        public static void main(String[] args) {
    
            try {
                Socket socket = new Socket("127.0.0.1", 5000);
                ConnectionToServer server = new ConnectionToServer(socket);
                System.out.println("[INFO] connet complete");
                messageHandler mHandler = new messageHandler(server);
                mHandler.start();
                String input="";
                BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
                while(true) {
                    input = keyboard.readLine();
                    if(input.equals("QUIT")){
                        break;
                    }
                    server.write(input);
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        static class messageHandler extends Thread {
            ConnectionToServer server;
    
            messageHandler(ConnectionToServer server) {
                this.server = server;
            }
    
            public void run() {
                try {
                    String initialLocation = "1 2";
                    String response = "";
                    server.write(initialLocation);
                    while ((response = server.read()) != null) {
                        System.out.println("response:" +response);
                        //drawMap(response);
                    }
                } catch (Exception e) {
                }
            }
        }
    
        static class ConnectionToServer {
            Socket socket;
            BufferedReader br;
            ObjectInputStream ois;
            PrintWriter pw;
    
            ConnectionToServer(Socket socket) {
                this.socket = socket;
                try {
                    br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    pw = new PrintWriter(socket.getOutputStream());
                    ois = new ObjectInputStream(socket.getInputStream());
                } catch (Exception e) {
                }
            }
    
            public void write(String obj) {
                pw.println(obj);
                pw.flush();
            }
    
            public String read() {
                try {
                    return (String) ois.readObject();
                } catch (Exception e) {
                    return null;
                }
            }
        }
    
        public static void drawMap(String command) {
            try {
                String[] yAndX = command.split(" ");
                int y = Integer.parseInt(yAndX[0]);
                int x = Integer.parseInt(yAndX[1]);
                String toPrint = "";
                for (int i = 0; i < 3; i++) {
                    toPrint = "";
                    for (int j = 0; j < 3; j++) {
                        if (y == i && x == j) {
                            toPrint += "* ";
                            continue;
                        }
                        toPrint += ". ";
                    }
                    System.out.println(toPrint);
                }
            } catch (Exception e) {
            }
        }
    }
    
    • 감사합니다.^^ 해결됐어요. 추가로 궁금한 점이 있는데 메인에서 while돌면서 서버에서 받아오도록 하고, 쓰레드 안에서 키보드 입력을 기다리도록 하면 제대로 동작하지 않던데 왜 그런지 혹시 알 수 있을까요??? 알 수 없는 사용자 2016.4.7 18:35

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)