ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 서버 통신
    공부 2022. 7. 28. 11:11
    728x90

    크롬으로 접속하여

    접속한 소켓에만 답장을 해주고, HTTP 응답 프로토콜 형태로 응답

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.List;

    public class WebServer {
        static List<Socket> socketList;
        public static void main(String[] args) throws IOException {
            socketList = new ArrayList<>();
            ServerSocket ss= new ServerSocket(9999);
            System.out.println("Server Started");
            while(true){
                Socket cs=ss.accept();
                socketList.add(cs); // 여러 명의 클라이언트가 접속  
                System.out.println("[" + cs.getInetAddress() + ":" + cs.getPort() + "]가 입장했습니다.");  
                System.out.println("clients: "+socketList.size());          
                WebServerReceiver receiver=new WebServerReceiver(cs);
                receiver.start();

            }
        }
    }
    class WebServerReceiver extends Thread{
        Socket cs;
        WebServerReceiver(Socket cs){
            this.cs=cs;
        }
        public void run(){

            try{
                InputStream is =cs.getInputStream(); //상대방으로부터 읽을 수 있는 스트림
    //            DataInputStream dis = new DataInputStream(is);  
                BufferedReader br=new BufferedReader(new InputStreamReader(is));
                String msg;
                while((msg=br.readLine())!=null){
                    System.out.println(msg);                
                    if(msg.isEmpty()){
                        break;
                    }              
                }
                sendToClient(msg);
            }catch(IOException e){
                throw new RuntimeException();
            }            
        }
        void sendToClient(String msg){
            try{
                OutputStream os = cs.getOutputStream();
    //            DataOutputStream dos=new DataOutputStream(os);
                PrintWriter pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(os)));
                pw.write("HTTP/1.1 200 OK\r\n");
                pw.write("\r\n");
                pw.write("<title>test</title>");
                pw.write("<p>test page</p>");
                pw.close();
                cs.close();
               
            }catch(IOException e){
                throw new RuntimeException(e);
            }
        }
    }

     

    웹서버처럼 동작하게 만들기

    package server;


    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.SocketException;
    import java.util.ArrayList;
    import java.util.List;

    public class WebServer {
        static List<Socket> socketList;
        public static void main(String[] args) throws IOException {
            socketList = new ArrayList<>();
            ServerSocket ss= new ServerSocket(9999);
            System.out.println("Server Started");
            while(true){
                Socket cs=ss.accept();
                socketList.add(cs); // 여러 명의 클라이언트가 접속  
                System.out.println("[" + cs.getInetAddress() + ":" + cs.getPort() + "]가 입장했습니다.");  
                System.out.println("clients: "+socketList.size());          
                WebServerReceiver receiver=new WebServerReceiver(cs);
                receiver.start();

            }
        }
    }
    class WebServerReceiver extends Thread{
        Socket cs;
        WebServerReceiver(Socket cs){
            this.cs=cs;
        }
        public void run(){

            try{
                InputStream is =cs.getInputStream(); //상대방으로부터 읽을 수 있는 스트림
    //            DataInputStream dis = new DataInputStream(is);  
                BufferedReader br=new BufferedReader(new InputStreamReader(is));
                String msg;
                while((msg=br.readLine())!=null){
                    System.out.println(msg);                
                    sendToClient(msg);
                    break;  
                }
               
            }catch (SocketException e) {
                WebServer.socketList.remove(cs);
                System.out.println("[" + cs.getInetAddress() + ":" + cs.getPort() + "] was left");
                System.out.println("clients : " + WebServer.socketList.size());
            }catch(IOException e){
                throw new RuntimeException();
            }            
        }
        void sendToClient(String requestLine){
            String filePath=requestLine.split(" ")[1];
            String realPath="파일 주소"+filePath;
            System.out.println(realPath);
            try{
                OutputStream os = cs.getOutputStream();
    //            DataOutputStream dos=new DataOutputStream(os);
                PrintWriter pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(os)));
                BufferedReader br = new BufferedReader(new FileReader(realPath));
                pw.write("HTTP/1.1 200 OK\r\n");
                pw.write("\r\n");
                while (true) {
                    String line = br.readLine();
                    if (line == null) break;
                    pw.write(line+"\r\n");
                }
                br.close();
                pw.close();
                cs.close();
               
            }catch(IOException e){
                throw new RuntimeException(e);
            }
        }
    }

     

     

    topic 주제

    to 주소/message

    발행자가 메시지를 보낼 때는

    [topic:a] message

    [topic:b] message

    [topic:c] message

     

    구독자

    [a,b]

    [c]

     

    구독자

    cs1

             [a]                            

                                             

    cs2

             [b]

     

    cs3

             [a,c]

     

    HashMap<String,List<Socket>>

    "a":[cs1,cs3]        "b":[cs2]       "c":[cs2,cs3]

     

    topic만 파싱해서 해당 topic이 hashmap에 키가 있으면 값(LIst)을 get해서 해당 리스트에 클라이언트 소켓을 add한다.

    해당 topic이 hashmap에 키가 없으면 새로운 List를 생성해서 해당 리스트에 클라이언트 소켓을 add하고,

    해당 리스트를 hashmap에 put(topic,List)한다.

     

     

    서버

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;

    public class PubSubServer {
        static HashMap<String,HashSet<Socket>>topicList=new HashMap<>();
        static List<Socket> socketList;
        public static void main(String[] args) throws IOException {
            socketList = new ArrayList<>();
            ServerSocket ss = new ServerSocket(9999);
            System.out.println("Server Started...");
            while (true) {
                Socket cs = ss.accept();
                socketList.add(cs);
                System.out.println("[" + cs.getInetAddress() + ":" + cs.getPort() + "] was conneted");
                System.out.println("clients : " + socketList.size());
                PubServerReceiver sr = new PubServerReceiver(cs);
                sr.start();
            }
        }
    }
    class PubServerReceiver extends Thread {
        Socket cs;

        PubServerReceiver(Socket cs) {
            this.cs = cs;
        }

        void fromSub(String message) {
            String topics = message.substring(1,message.length()-1);
            System.out.println(topics);

            for(String topic:topics.split(",")){
                if(!PubSubServer.topicList.containsKey(topic)){
                    HashSet<Socket>topicSocketSet=new HashSet<>();
                    topicSocketSet.add(cs);
                    PubSubServer.topicList.put(topic, topicSocketSet);
                }else{
                    System.out.println(PubSubServer.topicList.get(topic));
                    PubSubServer.topicList.get(topic).add(cs);
                    System.out.println(PubSubServer.topicList.get(topic));
                }
            }
        }

        void fromPub(String message){
            String topic=message.substring(7,8);
            String msg=message.substring(9);
            try {
                for (Socket client : PubSubServer.topicList.get(topic)) {
                    OutputStream os = client.getOutputStream();
                    DataOutputStream dos = new DataOutputStream(os);
                    dos.writeUTF(msg);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public void run() {
            try {
                InputStream is = cs.getInputStream();
                DataInputStream dis = new DataInputStream(is);
                while (dis != null) {
                    String message = dis.readUTF();
                    if(message.contains("topic")) {
                        fromPub(message);
                    }else {
                        fromSub(message);
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    구독자 클라이언트

    public class Client05 {
        public static void main(String[] args) throws IOException {
            //연결 부분
            Socket cs= new Socket("ip주소",9999);
            Sender_1 sender = new Sender_1(cs);
            sender.start();

            Receiver_1 receiver=new Receiver_1(cs);
            receiver.start();
        }
    }
     
     
    발행자 클라이언트
     
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.Scanner;

    public class PubClient {
        public static void main(String[] args) throws UnknownHostException, IOException {
            Socket cs= new Socket("192.168.1.13",9999);
            PubSender pubSender = new PubSender(cs);
            pubSender.start();
        }
    }
    class PubSender extends Thread{
        Socket cs;
        PubSender(Socket cs){
            this.cs=cs;
        }
        public void run(){
            try {
                OutputStream os = cs.getOutputStream();
                DataOutputStream dos=new DataOutputStream(os);
                Scanner scanner=new Scanner(System.in);
                while(dos!=null){
                    String msg=scanner.nextLine();
                    if(msg.equals("quit")){
                        return;
                    }
                    dos.writeUTF(msg);
                }          
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
           
           
        }
    }

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    728x90
    반응형

    '공부' 카테고리의 다른 글

    kafka  (0) 2022.07.28
    HashMap  (0) 2022.07.28
    서버 클라이언트 통신  (0) 2022.07.27
    디자인 패턴 - 싱글톤  (0) 2022.07.27
    자바 쓰레드  (0) 2022.07.27

    댓글

Designed by Tistory.