ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 서버 클라이언트 통신
    공부 2022. 7. 27. 16:32
    728x90

    서버 계속 켜져 있는 상태

    서버

    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.*;
    public class Sever03_1 {
        public static void main(String[] args) throws IOException {
            ServerSocket ss=new ServerSocket(9999);
            while(true){
                Socket cs=ss.accept();
                OutputStream os = cs.getOutputStream();
                DataOutputStream dos=new DataOutputStream(os);
                dos.writeUTF("Hello~!");
                dos.close();
                cs.close();
            }
        }
    }

    클라이언트

    import java.io.DataInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;

    public class Client03 {
        public static void main(String[] args) throws UnknownHostException, IOException {
            Socket cs= new Socket("ip주소",9999);
            InputStream is = cs.getInputStream();
            DataInputStream dis=new DataInputStream(is);
            System.out.println(dis.readUTF());
            dis.close();
            cs.close();
        }
    }

    서버만 클라이언트에게 메시지를 보내는 형태

     

    서버

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.*;
    public class Sever03_1 {
        public static void main(String[] args) throws IOException {
            ServerSocket ss=new ServerSocket(9999);
            while(true){
                //연결 부분
                Socket cs=ss.accept();
                System.out.println("client IP: "+cs.getInetAddress());
                System.out.println("client Post: "+cs.getPort());

                //데이터 수신 부분
                InputStream is =cs.getInputStream(); //상대방으로부터 읽을 수 있는 스트림
                DataInputStream dis = new DataInputStream(is);
                String data=dis.readUTF();
                System.out.println(data);
               
                //데이터 전송 부분
                OutputStream os = cs.getOutputStream();
                DataOutputStream dos=new DataOutputStream(os);
                dos.writeUTF("echo "+data);
               
                //연결 해제 부분
                dos.close();
                cs.close();
                dis.close();
                is.close();
            }
        }
    }

    클라이언트

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.Scanner;

    public class Client03 {
        public static void main(String[] args) throws UnknownHostException, IOException {
            //연결 부분
            Socket cs= new Socket("192.168.1.13",9999);

            //데이터 전송 부분
            Scanner scanner = new Scanner(System.in);
            String msg=scanner.nextLine();        
            OutputStream os = cs.getOutputStream();
            DataOutputStream dos=new DataOutputStream(os);
            dos.writeUTF(msg);
           
            //데이터 수신 부분
            InputStream is = cs.getInputStream();
            DataInputStream dis=new DataInputStream(is);
            System.out.println(dis.readUTF());
           
            dos.close();
            os.close();
            dis.close();
            cs.close();
        }
    }

    서버에서 클라이언트와 연결, 클라이언트에서 메세지를 보내면 서버에서 echo를 붙여 클라이언트에게 다시 보냄

    코드 순서가 잘못 되면 에러가 생길 수 있어 주의해야 된다.

    서버에서는 input 후 output

    클라이언트에서는 output 후 input 해야한다.

     

    1:1 채팅

    서버

    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.Scanner;

    public class Sever04 {
        public static void main(String[] args) throws IOException {
            ServerSocket ss=new ServerSocket(9999);
            System.out.println("Server Started...");
           
            Socket cs=ss.accept();

            //수신 부분
            Receiver_1 receiver=new Receiver_1(cs);
            receiver.start();

            //전송 부분
            Sender_1 sender=new Sender_1(cs);
            sender.start();
           
        }
    }
    class Receiver_1 extends Thread{
        Socket cs;
        Receiver_1(Socket cs){
            this.cs=cs;
        }
        public void run(){
            try{
                InputStream is =cs.getInputStream(); //상대방으로부터 읽을 수 있는 스트림
                DataInputStream dis = new DataInputStream(is);
                while(dis!=null){    
                    System.out.println("["+cs.getInetAddress()+":"+cs.getPort()+"] "+dis.readUTF());
                }
            }catch(IOException e){
                throw new RuntimeException();
            }
           
               
        }
    }

    class Sender_1 extends Thread{
        Socket cs;
        Sender_1(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();
                    dos.writeUTF(msg);
                }          
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
           
           
        }
    }
     

    클라이언트

    import java.io.IOException;
    import java.net.Socket;

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

            Receiver_1 receiver=new Receiver_1(cs);
            receiver.start();
        }
    }

     

    클라이언트가 여러명 접속

    서버

    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.List;

    public class Server05 {
        public static void main(String[] args) throws IOException {
            List<Socket> socketList = new ArrayList<>();
            ServerSocket ss= new ServerSocket(9999);
            System.out.println("Server Started");
            while(true){
                Socket cs=ss.accept();
                socketList.add(cs); // 여러 명의 클라이언트가 접속
                for(Socket client:socketList){
                    System.out.println(client.getInetAddress()+" : "+client.getPort());
                }
            }
        }
    }

     

    여러명의 클라이언트가 접속했는지 알 수 있지만, 클라이언트가 접속을 끊은 경우 알 수 없다.

     

     

    클라이언트가 서버에게 메시지를 보내면

    서버는 받은 메시지를 모든 클라이언트에게 전송

    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.List;

    public class Server05 {
        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); // 여러 명의 클라이언트가 접속                
                Receiver_2 receiver=new Receiver_2(cs);
                receiver.start();

            }
        }
    }
    class Receiver_2 extends Thread{
        Socket cs;
        Receiver_2(Socket cs){
            this.cs=cs;
        }
        public void run(){
            String msg;
            try{
                InputStream is =cs.getInputStream(); //상대방으로부터 읽을 수 있는 스트림
                DataInputStream dis = new DataInputStream(is);          
                while(dis!=null){
                    msg=dis.readUTF();  
                    for(Socket send:Server05.socketList){
                        if(send==cs) continue;
                        OutputStream os = send.getOutputStream();
                        DataOutputStream dos=new DataOutputStream(os);
                        dos.writeUTF(msg);
                    }                
                }
            }catch(IOException e){
                throw new RuntimeException();
            }            
        }
    }
    자기 자신이 보낸 메시지 제외하고 받음
     
    보낸 클라이언트의 ip주소, port번호 포함하여 보냄

    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.List;

    public class Server05 {
        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); // 여러 명의 클라이언트가 접속                
                Receiver_2 receiver=new Receiver_2(cs);
                receiver.start();

            }
        }
    }
    class Receiver_2 extends Thread{
        Socket cs;
        Receiver_2(Socket cs){
            this.cs=cs;
        }
        public void run(){
            String msg;
            try{
                InputStream is =cs.getInputStream(); //상대방으로부터 읽을 수 있는 스트림
                DataInputStream dis = new DataInputStream(is);          
                while(dis!=null){
                    msg=dis.readUTF();
                    String str="["+cs.getInetAddress()+":"+cs.getPort()+"] "+msg;
                    for(Socket send:Server05.socketList){
                        if(send==cs) continue;
                        OutputStream os = send.getOutputStream();
                        DataOutputStream dos=new DataOutputStream(os);
                        dos.writeUTF(str);
                    }                
                }
            }catch(IOException e){
                throw new RuntimeException();
            }            
        }
    }

    클라이언트가 접속을 종료할 때 SocketException 에러가 발생하는데, SocketException에 대한 예외처리로 socketList에서 해당 클라이언트를 삭제(socketlist.remove()), 남아 있는 사용자들에게 나간 사용자의 [IP: 포트] 가 나갔습니다. 표시

    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.List;

    public class Server05 {
        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("clients: "+socketList.size());          
                Receiver_2 receiver=new Receiver_2(cs);
                receiver.start();

            }
        }
    }
    class Receiver_2 extends Thread{
        Socket cs;
        Receiver_2(Socket cs){
            this.cs=cs;
        }
        public void run(){
            String msg;
            try{
                InputStream is =cs.getInputStream(); //상대방으로부터 읽을 수 있는 스트림
                DataInputStream dis = new DataInputStream(is);          
                while(dis!=null){
                    msg=dis.readUTF();
                    String str="["+cs.getInetAddress()+":"+cs.getPort()+"] "+msg;
                    for(Socket send:Server05.socketList){
                        if(send==cs) continue;
                        OutputStream os = send.getOutputStream();
                        DataOutputStream dos=new DataOutputStream(os);
                        dos.writeUTF(str);
                    }                
                }
            }catch(IOException e){
                String str="["+cs.getInetAddress()+":"+cs.getPort()+"]가 나갔습니다. ";
                Server05.socketList.remove(cs);
                System.out.println("clients: "+Server05.socketList.size());  
                for(Socket send:Server05.socketList){
                    OutputStream os;
                    try {
                        os = send.getOutputStream();
                        DataOutputStream dos=new DataOutputStream(os);
                        dos.writeUTF(str);
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                   
                }
            }            
        }
    }

     

     

     

     

    728x90
    반응형

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

    HashMap  (0) 2022.07.28
    서버 통신  (0) 2022.07.28
    디자인 패턴 - 싱글톤  (0) 2022.07.27
    자바 쓰레드  (0) 2022.07.27
    네트워크 스트림  (0) 2022.07.26

    댓글

Designed by Tistory.