Java 103(ServerSocket, Socket, TCP Network, 날짜와 시간을 제공하는 서버 프로그램)

Kang.__.Mingu·2024년 5월 23일
0

Java

목록 보기
105/108

ServerSocket

  • 서버 프로그램을 작성하기 위해 사용하는 클래스

  • ServerSocket(int port) 생성자를 사용하여 ServerSocket 객체 생성

  • port 매개변수에는 클라이언트가 접속할 수 있는 포트번호를 전달해 포트 활성화 처리

  • 매개변수로 전달받은 포트번호가 다른 네트워크 프로그램에서 사용중인 경우 IOException 발생

new ServerSocket(2000); 

ServerSocket 메소드

  • ServerSocket.toString()

    • ServerSocket 객체에 저장된 네트워크 정보를 문자열로 반환하는 메소드
  • ServerSocket.close()

    • ServerSocket 객체를 제거하는 메소드 - 서버 종료

    • 접속중인 모든 클라이언트와의 접속 해제

Socket

  • TCP 프로그램에서 호스트와의 연결 정보가 저장된 객체를 생성하기 위한 클래스

  • Socket(String host, int port): 생성자를 사용하여 Socket 객체 생성 - 서버 접속

  • host 매개변수에는 접속할 서버의 이름 또는 IP 주소를 전달하고 port 매개변수에는 서버에서 활성화 처리된 포트번호를 전달하여 객체 생성

  • UnknownHostException 및 IOException 발생

  • 서버에 접속되면 서버의 소켓과 연결되어 데이터를 송수신 할 수 있는 입력스트림과 출력스트림이 자동 생성돼 Socket 객체에 저장

Socket 메소드

  • Socket.accept()

    • 클라이언트가 서버에 접속하면 클라이언트와 데이터를 송수신 할 수 있는 Socket 객체를 반환하는 메소드

    • 클라이언트가 접속되기 전까지 스레드가 일시 중지되며 클라이언트가 서버에 접속되면 클라이언트의 소켓과 연결된 소켓을 생성한 후 스레드 재실행

  • Socket.getOutputStream()

    • Socket 객체로부터 접속된 클라이언트에게 원시데이터를 전달할 수 있는 출력스트림(OutputStream 객체)를 반환하는 메소드

    • 매개변수로 클라이언트로 원시데이터를 전달할 수 있는 OutputStream 객체를 전달받아 객체를 전달할 수 있는 출력스트림(ObjectOutputStream 객체)으로 확장

  • Socket.getInetAddress()

    • Socket 객체에 저장된 접속 컴퓨터의 네트워크 식별자가 저장된 InetAddress 객체를 반환하는 메소드
  • Socket.close()

    • Socket 객체를 제거하는 메소드 - 접속된 클라이언트와의 연결 해제
  • Socket.getInputStream()

    • Socket 객체로부터 접속된 서버에서 보내온 원시데이터를 전달받을 수 있는 입력스트림(inputStream 객체)를 반환하는 메소드

  • TCP 네트워크 프로그램: ServerSocket 클래스와 Socket 클래스를 사용하여 작성

  • 클라이언트가 서버에 접속하여 서버와 클라이언트의 소켓을 사용해 1:1로 연결되어 데이터를 송수신하는 프로그램

TimeServerApp

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

// 접속된 클라이언트에게 서버 컴퓨터의 현재 날짜와 시간이 저장된 객체를 전달하는 서버 프로그램
// => NTP(Network Time Protocol) Server: 날짜와 시간을 제공하는 서버
public class TimeServerApp {
    public static void main(String[] args) {
        // ServerSocket 클래스: 서버 프로그램을 작성하기 위해 사용하는 클래스
        ServerSocket ntpServer = null;
        try {
            // ServerSocket(int port) 생성자를 사용하여 ServerSocket 객체 생성
            // => port 매개변수에는 클라이언트가 접속할 수 있는 포트번호를 전달해 포트 활성화 처리
            // => 매개변수로 전달받은 포트번호가 다른 네트워크 프로그램에서 사용중인 경우 IOException 발생
            ntpServer = new ServerSocket(2000);

            // ServerSocket.toString(): ServerSocket 객체에 저장된 네트워크 정보를 문자열로 반환하는 메소드
            System.out.println("ntpServer = " + ntpServer);

            System.out.println("[메세지] NTP Server Running...");

            // 서버는 다수의 클라이언트가 접속되어 서비스를 제공받을 수 있도록 무한루프 사용
            while(true){
                // Socket.accept(): 클라이언트가 서버에 접속하면 클라이언트와 데이터를 송수신
                // 할 수 있는 Socket 객체를 반환하는 메소드
                // => 클라이언트가 접속되기 전까지 스레드가 일시 중지되며 클라이언트가 서버에
                // 접속되면 클라이언트의 소켓과 연결된 소켓을 생성한 후 스레드 재실행
                Socket socket = ntpServer.accept();
                // System.out.println("socket = " + socket);

                // Socket.getOutputStream(): Socket 객체로부터 접속된 클라이언트에게 원시데이터를 전달할 수 있는
                // 출력스트림(OutputStream 객체)를 반환하는 메소드
                OutputStream outputStream = socket.getOutputStream();

                // 매개변수로 클라이언트로 원시데이터를 전달할 수 있는 OutputStream 객체를 전달받아
                // 객체를 전달할 수 있는 출력스트림(ObjectOutputStream 객체)으로 확장
                ObjectOutputStream out = new ObjectOutputStream(outputStream);

                // 확장된 출력스트림으로 플렛폼의 현재 날짜와 시간이 저장된 Date 객체를 클라이언트에게 전달
                out.writeObject(new Date());

                // 불필요한 식별자를 제거하여 작성된 명령 => 위의 명령을 간소화
                // new ObjectOutputStream(socket.getOutputStream()).writeObject(new Date());

                // 로그 처리 - 기록
                // Socket.getInetAddress(): Socket 객체에 저장된 접속 컴퓨터의 네트워크 식별자가
                // 저장된 InetAddress 객체를 반환하는 메소드
                System.out.println("[정보] 클라이언트 [ " + socket.getInetAddress().getHostAddress() +
                    " ]에게 날짜와 시간을 제공 하였습니다.");

                // Socket.close(): Socket 객체를 제거하는 메소드 - 접속된 클라이언트와의 연결 해제
                socket.close();
            }

        } catch (IOException e) {
            System.out.println("[에러] 서버 네트워크에 문제가 발생 되었습니다.");
        } finally {
            try {
                // ServerSocket.close(): ServerSocket 객체를 제거하는 메소드 - 서버 종료
                // => 접속중인 모든 클라이언트와의 접속 해제
                ntpServer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

TimeClientApp

public class TimeClientApp {
    public static void main(String[] args) throws ClassNotFoundException {
        try {
            // Socket 클래스: TCP 프로그램에서 호스트와의 연결 정보가 저장된 객체를 생성하기 위한 클래스
            // => Socket(String host, int port): 생성자를 사용하여 Socket 객체 생성 - 서버 접속
            // => host 매개변수에는 접속할 서버의 이름 또는 IP 주소를 전달하고 port 매개변수에는
            // 서버에서 활성화 처리된 포트번호를 전달하여 객체 생성
            // => UnknownHostException 및 IOException 발생
            // => 서버에 접속되면 서버의 소켓과 연결되어 데이터를 송수신 할 수 있는 입력스트림과 출력스트림이
            // 자동 생성돼 Socket 객체에 저장
            Socket socket = new Socket("xxx.xxx.xxx.xxx", 2000);
            // xxx.xxx.xxx.xxx => 내 아이피 넣으면 됨
            // System.out.println("socket = " + socket);

            // Socket.getInputStream(): Socket 객체로부터 접속된 서버에서 보내온 원시데이터를 전달받을 수 있는
            // 입력스트림(inputStream 객체)를 반환하는 메소드
            InputStream inputStream = socket.getInputStream();

            // 매개변수로 서버에서 보내온 원시데이터를 받을 수 있는 OutputStream 객체를 전달받아
            // 객체를 반환받기 위한 입력스트림(ObjectInputStream 객체)으로 확장
            ObjectInputStream in = new ObjectInputStream(inputStream);

            // 확장된 입력스트림으로 서버에서 보내온 현재 날짜와 시간이 저장된 Date 객체를 반환받아 저장
            // => 확장된 입력스트림에 객체가 없는 경우 스레드 일시 중지되며 객체가 전달되면 스레드 재실행

            // (객체로 들고오기 때문에)명시적 객체 형변환 진행
            Date date = (Date) in.readObject();

            System.out.println("[결과] 과연? 서버에서 보내온 날짜와 시간 = " +
                new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(date));

            socket.close();
        } catch (UnknownHostException e) {
            System.out.println("[에러] 서버를 찾을 수 없습니다.");
        } catch (IOException e) {
            System.out.println("[에러] 서버에 접속할 수 없습니다.");
        }
    }
}
profile
최선을 다해 꾸준히 노력하는 개발자 망고입니당 :D

0개의 댓글