Day 19. 국비교육 세번째 평가

ho_c·2022년 3월 20일
0

국비교육

목록 보기
19/71
post-thumbnail
post-custom-banner

오늘도 어김없이 보는 평가. 이번 주만 평가를 두 번이나 봤다.
평가 난이도가 높진 않지만, 매번 평가를 준비한다는 것은 부담이 꽤 된다.
그래도 평가 결과는 둘 다 만점이라서 기분이 좋다 😋


서술형

1. 서버(Server)에 대해 서술하시오.

서버의 정의는 '사용자에게 서비스를 제공하는 쪽'을 말한다. 특정 서비스를 만들어 배포하면, 해당 서비스의 프로그램은 서버쪽 컴퓨터에 마련되고 클라이언트는 포트를 통하여 해당 서비스를 이용하게 된다.
주로 서버는 1대 1의 통신 방식이 아닌 1 대 다수의 통신을 한다. 추가로 서버쪽 PC는 화면이 없다.

2. ServerSocket에 대해 서술하시오.

먼저 소캣은 네트워크 통신을 위한 논리적 단말기이다. 이 단말기가 있어야만 두 PC간의 통신이 이루어지는데, 중요한 것은 오직 1대 1통신만 가능하단 것이다.
따라서 1대 다수의 통신을 하는 서버의 입장에서 소캣이 1개만 있으면 서비스의 제공이 불가능하게 된다. 이를 해결하기 위해 만들어진 것이 서버 소캣으로, 일종의 소캣 공장이다.
먼저 이 공장은 .accept(); 라는 메서드를 통해 클라이언트의 접속이 올 때까지 내부의 무한루프 상태로 대기한다.
그러다가 IP와 포트번호를 통해 클라이언트가 서버에 접속하게 되면, .accept();는 클라이언트의 소캣과 연결되는 새로운 소캣을 만들어 반환하면서 내부의 루프를 탈출하여, 서버의 프로그램을 이어나간다.

3. Stream에 대해 최대한 자세히 서술하시오.

소캣이 네트워크 통신을 위한 논리적 단말기라면, Stream은 데이터가 오고 가게 하는 논리적 도로, 통로이다.
곧, 단말기로 연결이 되었어도 각 PC에서 데이터를 보내려면 Stream이라는 도로가 필요하다. 그리고 굳이 네트워크에 한정되지 않고 모든 데이터가 오고 갈 땐, Stream이 필요하다.
이런 Stream은 2가지가 존재하는데, 1개는 데이터를 내보내는 OutputStream이고, 다른 1개는 데이터를 받는 InputStream이다. 그 기준은 RAM으로 RAM으로 데이터가 들어오면 Input, RAM에서 데이터가 나가면 output이라고 한다.
기본적인 방식은 Buffer을 통해서 입력을 받고, Buffer가 꽉 차면 자동으로 데이터를 보내거나, 아니면 flush(); 메서드를 통해 강제로 Buffer를 비워서 데이터를 전송한다.
마지막으로 제일 중요한 것은 외부든, 내부든 네트워크 상에서 통신을 할 때 Stream간의 대치가 맞아야 한다.
즉, 한쪽에서 데이터를 보내면 다른 한쪽에선 데이터를 받는 코드가 정의되어야 한다. 이게 맞지 않으면 프로그램이 실행되지 않는다.


문제 해결

[ 문제 ]

개발자는 주민번호 뒷자리 6자리를 입력하여 전송하면, 날짜형식을 갖추어 반환하는 서비스 서버를 구상했다.

ex) 주민번호 뒷자리 6자리를 입력하세요 : 900505
서버로부터의 결과 : 1990년 05월 05일 (토)
그러나 다음의 코드는 원하는 결과를 만들지 못했다.
그 원인을 찾아내어 설명하고, 해결책을 제시하세요.

Server 코드

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.sql.Date;

public class Server {
	public static void main(String[] args) throws Exception{

		SimpleDateFormat from = new SimpleDateFormat("yyMMdd");
		SimpleDateFormat to = new SimpleDateFormat("yyyy년 MM월 dd일 (E)");
		ServerSocket server = new ServerSocket(25000);

		while(true) {
			Socket sock = server.accept();
			DataInputStream dis = new DataInputStream(sock.getInputStream());
			DataOutputStream dos = new DataOutputStream(sock.getOutputStream());

			String target = dis.readUTF();

			try {

				Date date = from.parse(target);
				String result = to.parse(date.getTime());
	
				dos.writeUTF(result);
			}catch(Exception e) {
				dos.writeUTF("날짜 형식이 잘 못 되었습니다.");
			}
			dos.flush();
		}
	}
}

Client 코드

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Client {

	public static void main(String[] args) throws Exception{

		Scanner sc = new Scanner(System.in);
		Socket sock = new Socket("127.0.0.1", 30000);
		DataInputStream dis = new DataInputStream(sock.getInputStream());
        DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
		System.out.print("주민번호 뒷자리 6자리를 입력하세요 : ");

        String date = sc.nextLine();
		dos.writeUTF(date);

		dos.flush();

		String result = dis.readUTF("date");

		System.out.println("서버로부터의 결과 : " + result);

	}
}

원인과 해결

Server 문제

1. Date 클래스 import 오류

java 내부에 Date 클래스가 있는 패키지는 sql이랑 util이 있다.
이 중 SimpleDateFormat을 사용하려면 util을 import해야된다.

2. 포트번호 문제

Cilent에서 설정한 포트번호와 Server에서 받기 위해 열어둔 포트번호가 서로 다르다.
ip주소가 맞아도 포트번호가 다르면 원하는 서버의 서비스로 연결되지 않는다.

3. String result = to.parse(date.getTime()); 메서드 오류

parse는 반환 자료형이 Date 클래스이며, 해당 메서드는 입력된 날짜의 표준시간을 특정 양식으로 반환한다.

ex) input​ 951107
    output Tue Nov 07 00:00:00 KST 1995

따라서 애초에 원하는 기능이 아니다. 원하는 것은 to인스턴스의 맞는 형식을 String으로 반환받는 것이다.

Client 문제

4. String result = dis.readUTF("date"); : 매개변수 오류

서버에서 데이터를 받는 readUTF(); 메서드는 2개가 오버로딩이 되어있다.
그 중 하나는 매개변수가 없고, 다른 하나는 DataInput 이라는 클래스의 참조변수이다.
따라서 인자값으로 "date"라는 String형을 넣어주면 오류가 난다.


profile
기록을 쌓아갑니다.
post-custom-banner

0개의 댓글