Скачать презентацию 14 14 3 19 2018 14장 Applet Скачать презентацию 14 14 3 19 2018 14장 Applet

631f7ff7028da29774af0c03b7a7f94b.ppt

  • Количество слайдов: 170

14 ██████ 14 3/19/2018 14 ██████ 14 3/19/2018

14장 Applet & Java Web Start 소설같은 3 자바 rd Edition since 2001 최영관 14장 Applet & Java Web Start 소설같은 3 자바 rd Edition since 2001 최영관 Powered by http: //www. jabook. org 3/19/2018

14. 1 애플릿의 기본 3/19/2018 14. 1 애플릿의 기본 3/19/2018

14. 1. 1 애플릿의 개요 ▣ 애플릿이란? ◈ ▣ 애플릿의 동작원리 ◈ ▣ <applet 14. 1. 1 애플릿의 개요 ▣ 애플릿이란? ◈ ▣ 애플릿의 동작원리 ◈ ▣ 클래스의 이름만 명시한 예 ◈ ◈ ▣ Applet Test Test. class를 명시한 예 ◈ ◈ ▣ HTML 문서에 애플릿이 포함된 예 ◈ ◈ ◈ ▣ 애플릿(Applet) 태그 ◈ ▣ HTML에 이미지가 그려지는 것과 애플릿 프로그램이 실행되는 것은 비슷한 원리로 동작한다. 이미지(IMG) 태그 ◈ ▣ 애플릿은 웹 브라우저에서 실행되는 자바 프로그램이다. 애플릿의 실행 ◈ 애플릿의 실행파일은 HTML 문서이며, 웹 브라우저를 이용해서 실행한다. 3/19/2018

14. 1. 2 애플릿의 간단 구현 ▣ 가장 간단한 애플릿 만들기 ◈ ◈ ◈ 14. 1. 2 애플릿의 간단 구현 ▣ 가장 간단한 애플릿 만들기 ◈ ◈ ◈ ◈ ▣ import java. awt. *; import java. applet. Applet; public class Test. Applet extends Applet{ public Test. Applet(){ //애플릿의 배경색 변경 this. set. Background(Color. orange); } } 애플릿을 포함하는 HTML 문서 ◈ ◈ ◈ Applet test 3/19/2018

14. 1. 3 애플릿에 그리기 작업 ▣ 애플릿에서 paint() 메서드의 재정의 ◈ ◈ ◈ 14. 1. 3 애플릿에 그리기 작업 ▣ 애플릿에서 paint() 메서드의 재정의 ◈ ◈ ◈ ◈ ▣ import java. awt. *; import java. applet. *; public class Hello. Applet extends Applet{ public void paint(Graphics g){ g. draw. String("Hello World", 50, 20); } } 애플릿을 포함하는 HTML 문서 문자그리기 Applet ◈ ◈ ◈ ◈ 3/19/2018

14. 1. 4 애플릿의 디버깅 ▣ 애플릿에서의 콘솔 출력 ◈ ◈ ◈ ◈ ▣ 14. 1. 4 애플릿의 디버깅 ▣ 애플릿에서의 콘솔 출력 ◈ ◈ ◈ ◈ ▣ import java. awt. *; import java. awt. event. *; import java. applet. *; public class Console. Applet extends Applet implements Action. Listener{ private int count = 0; private Button b 1 = new Button("콘솔출력"); public Console. Applet(){ this. add(b 1); b 1. add. Action. Listener(this); } public void action. Performed(Action. Event e){ System. out. println("호출횟수" + count++ ); } } 애플릿을 포함하는 HTML 문서 ◈ ◈ 콘솔 출력 Applet 3/19/2018

3/19/2018 3/19/2018

14. 2 애플릿의 주기 3/19/2018 14. 2 애플릿의 주기 3/19/2018

14. 2. 1 애플릿의 기본 주기 ▣ 애플릿의 상태 변화 ◈ 웹 브라우저의 특성상 14. 2. 1 애플릿의 기본 주기 ▣ 애플릿의 상태 변화 ◈ 웹 브라우저의 특성상 애플릿 프로그램의 상태는 웹 브라우저의 상태 변화 에 따라서 달라져야 한다. init() ▣ 애플릿의 주기 메서드 ◈ ◈ ◈ ▣ public void init(); public void start(); public void paint(Graphics g); public void stop(); public void destroy(); 애플릿의 주기 ◈ init(), start() paint() stop() destroy() Internet Explorer에서는 애플릿이 시작될 때 init()과 start()가 함께 호출되고, 웹 브라우저를 종료하 거나 다른 페이지로 이동할 때 stop()과 destroy()가 함께 호출된 다. start() 최초 시작시 단한번 호 출 페이지를 처음으로 시 작하거나 다른 페이지 에서 되돌아올 때 호출 paint() stop() destroy() 다른페이지로 이동시호출 종료시 단한번 호출 Netscape에서의 애플릿은 HTML 내에 삽입되어 실행되는 프로그램이기 때문에 웹 브라우 저가 실행되면 자동으로 호출되었다가 웹 브라우저를 닫으면 자동으로 종 료된다. 이 때 애플릿에 주기는 웹 브라우저의 상태 변화에 따라 결정된다. 3/19/2018

14. 2. 2 애플릿의 주기 테스트 ▣ ▣ ▣ ▣ ▣ import java. awt. 14. 2. 2 애플릿의 주기 테스트 ▣ ▣ ▣ ▣ ▣ import java. awt. *; import java. applet. *; public class Cycle. Applet extends Applet { public void init() { System. out. println("init() 호출"); } public void start(){ this. set. Background(Color. orange); System. out. println("start() 호출"); } public void paint(Graphics g){ System. out. println("paint() 호출"); } public void stop(){ System. out. println("stop() 호출"); } public void destroy() { System. out. println("destroy() 호출"); } } 3/19/2018

14. 2. 3 애플릿의 동작원리 ▣ 애플릿을 만드는 측면 ◈ Applet을 상속받아 주기 메서드를 14. 2. 3 애플릿의 동작원리 ▣ 애플릿을 만드는 측면 ◈ Applet을 상속받아 주기 메서드를 재정의한다. 애플릿을 실행하면 주기 메서드에 따라서 가상머신 내부에서 알아서 메서 드를 호출해준다. ◈ 가상 메서드의 원리에 의해 재정의된 주기 메서드가 호출된다. ◈ ▣ 애플릿 클래스 객체 생성 class Xxx extends Applet{. . . } ◈ 동적으로 Xxx 클래스의 객체 생성(리플렉션의 기법을 이용) ◈ 동적으로 생성된 Xxx형의 객체를 obj라고 가정 ◈ ▣ 가상머신 내부적으로 애플릿을 로딩한 후 실행 Applet app = (Applet)obj; ◈ app. init(); ◈ app. start(); ◈ 3/19/2018

14. 3 애플릿 프로그램 3/19/2018 14. 3 애플릿 프로그램 3/19/2018

14. 3. 1 애플릿에서 이미지 그리기 ▣ ▣ ▣ ▣ ▣ public class Image. 14. 3. 1 애플릿에서 이미지 그리기 ▣ ▣ ▣ ▣ ▣ public class Image. Load. Applet extends Applet { private Image img 1 = null; private Image img 2 = null; public void init() { img 1 = this. get. Image(get. Document. Base(), ". /eye. jpg"); 이미지 로딩 img 2 = this. get. Image(get. Code. Base(), ". /paintshop. jpg"); Media. Tracker tracker = new Media. Tracker(this); tracker. add. Image(img 1, 0); 이미지 로딩 보장 tracker. add. Image(img 2, 1); try{ tracker. wait. For. All(); }catch(Interrupted. Exception e){e. print. Stack. Trace(); } } public void paint(Graphics g) { if(img 1 != null) g. draw. Image(img 1, 20, this); 이미지 그리기 if(img 2 != null) g. draw. Image(img 2, 80, 20, this); } } 3/19/2018

14. 3. 2 애플릿에서 사운드 테스트 ▣ ▣ ▣ ▣ ▣ ▣ ▣ public 14. 3. 2 애플릿에서 사운드 테스트 ▣ ▣ ▣ ▣ ▣ ▣ ▣ public class Audio. Load. Applet extends Applet implements Action. Listener{ private Audio. Clip audio=null; private Button b 1 = new Button("play"); private Button b 2 = new Button("stop"); private Button b 3 = new Button("loop"); public void init() { this. audio = get. Audio. Clip(get. Code. Base(), ". /sp. au"); this. add(b 1); this. add(b 2); this. add(b 3); this. b 1. add. Action. Listener(this); this. b 2. add. Action. Listener(this); this. b 3. add. Action. Listener(this); } public void action. Performed(Action. Event e){ Object obj = e. get. Source(); if(obj == b 1){ audio. play(); }else if(obj == b 2){ audio. stop(); }else if(obj == b 3){ audio. loop(); } } } 3/19/2018

14. 3. 3 애플릿에서 창 띄우기 ▣ 애플릿에서 띄우는 프레임(창) ◈ ◈ ◈ ◈ 14. 3. 3 애플릿에서 창 띄우기 ▣ 애플릿에서 띄우는 프레임(창) ◈ ◈ ◈ ◈ ▣ public class Test. Frame extends Frame implements Window. Listener{ public Test. Frame(){ this. add. Window. Listener(this); this. set. Background(Color. orange); } public void window. Closing(Window. Event e){ this. dispose(); } public void window. Activated(Window. Event e){ } public void window. Closed(Window. Event e){ } public void window. Deactivated(Window. Event e){ } public void window. Deiconified(Window. Event e){ } public void window. Iconified(Window. Event e){ } public void window. Opened(Window. Event e){ } } 애플릿에서 창 띄우기 ◈ ◈ ◈ ◈ public class Show. Frame. Applet extends Applet implements Action. Listener{ private Button b 1 = new Button("창띄우기"); public Show. Frame. Applet(){ this. add(b 1); b 1. add. Action. Listener(this); } public void action. Performed(Action. Event e){ Test. Frame f = new Test. Frame(); f. set. Size(200, 200); f. set. Title("애플릿 내에서 창만들기"); f. set. Visible(true); } } 3/19/2018

14. 4 Java Web Start 3/19/2018 14. 4 Java Web Start 3/19/2018

14. 4. 1 Java Web Start란? ▣ 웹으로 배포하는 기술 ◈ 자바의 Applet ◈ 14. 4. 1 Java Web Start란? ▣ 웹으로 배포하는 기술 ◈ 자바의 Applet ◈ MS의 Active. X ▣ Applet의 문제점 ◈ 웹브라우저의 허락을 얻어야만 하는 기술이기 때문에 웹브라우저에 의존적인 기술이다. ▣ Java Web Start ◈ 웹을 통해 자바 애플리케이션 프로그램을 배포하는 새로운 기술 ◈ Java 1. 4부터 지원 Java Web Start Architecture Client 요청 1. 분석 JNLP 페이지 요청 JNLP 페이지 다운로드 Application 파일 요청 4. 실행 2. 요청 3. 다운로드 Javatm Web Start Client 3/19/2018 Application 다운로드 Application 관련 파일(jar파일) Web Application Server

14. 4. 2 Java Web Start의 특징 ▣ 웹브라우저에 의존적이지 않다. 한번의 클릭으로 자동 14. 4. 2 Java Web Start의 특징 ▣ 웹브라우저에 의존적이지 않다. 한번의 클릭으로 자동 다운로드 및 캐싱(Caching)되어 실행되는 프로그램 이다. ◈ 웹서버로부터 배포되어 실행되는 프로그램이다. ◈ 웹브라우저와 별개로 프로그램을 실행시킬 수 있다. ◈ ▣ 완벽한 플랫폼의 독립이다. ◈ ◈ ▣ 자바 플랫폼의 보안 기능을 그대로 사용한다. ◈ ◈ ▣ 웹브라우저의 독립으로 완벽한 플랫폼의 독립을 이루었다. 브라우져에서 지원하는 가상머신 버전과 보안에 신경 쓰지 않아도 된다. 기본적으로 네트워크 자원에 대한 Sand. Box 보호환경에서 실행된다. Java 보안 모델인 Signed Application을 이용할 수 있다. 강력한 클라이언트 인터페이스 ◈ ◈ 강력한 자바 UI 기술을 이용해서 클라이언트 프로그램을 구현할 수 있다. 다양한 플랫폼에서 동일한 User Interface로 클라이언트 프로그램을 실행할 수 있다. 3/19/2018

14. 5 Hello Java Web Start 3/19/2018 14. 5 Hello Java Web Start 3/19/2018

14. 5. 1 Java Web Start 7단계 ▣ Java Web Start 구축(로컬에서 구축) ◈ 14. 5. 1 Java Web Start 7단계 ▣ Java Web Start 구축(로컬에서 구축) ◈ ◈ ◈ ▣ 웹서버에 배포하기 ◈ ◈ ▣ 1단계 : 자바 Application 개발 2단계 : JNLP 파일 생성하기 3단계 : jnlp 파일 실행하기 4단계 : 웹서버 환경구축하기 5단계 : 톰캣에서 가상 디렉터리 지정 6단계 : JNLP 파일 수정하기 7단계 : Html 파일 작성 및 웹서버에 배포하기 Java Web Start 기술들 ◈ ◈ ◈ 리소스 접근하기 JNLP Package API Singed Application 만드는 방법 JNLP 파일의 구조 JRE 자동 설치 3/19/2018

14. 5. 2 단계 1 : 자바 애플리케이션 개발하기 ▣ ▣ ▣ ▣ ▣ 14. 5. 2 단계 1 : 자바 애플리케이션 개발하기 ▣ ▣ ▣ ▣ ▣ ▣ public class JWSFrame extends Frame implements Action. Listener{ private Button b 1 = new Button("누르세요"); 클라이언트의 로컬 자원을 이용하지 않는다. public JWSFrame(){ this. set. Layout(new Flow. Layout()); this. add(b 1); this. b 1. add. Action. Listener(this); this. add. Window. Listener(new Window. Adapter(){ public void window. Closing(Window. Event e){ System. exit(0); } }); } public void action. Performed(Action. Event e){ Graphics g = this. get. Graphics(); g. draw. String("Java Web Start!!!!", 100); System. out. println("Java Web Start Console 출력"); g. dispose(); } 컴파일 후 jar 파일로 묶기 public static void main(String[] args){ Frame f = new JWSFrame(); javac *. java f. set. Size(300, 300); jar cvf hello-jws. jar *. class f. set. Visible(true); } } 3/19/2018

14. 5. 3 단계 2 : jnlp 파일 생성하기 ▣ ▣ ▣ ▣ ▣ 14. 5. 3 단계 2 : jnlp 파일 생성하기 ▣ ▣ ▣ ▣ ▣ Hello Java Web Start Application JABOOK Hello Java Web Start Application 리소스(클래스, 이미지, 데이터) 실행클래스 3/19/2018

14. 5. 4 단계 3 : jnlp 실행하기 더블클릭 3/19/2018 14. 5. 4 단계 3 : jnlp 실행하기 더블클릭 3/19/2018

14. 5. 5 단계 4 : 웹서버 환경 구축하기 ▣ 웹서버 환경 구축 ◈ 14. 5. 5 단계 4 : 웹서버 환경 구축하기 ▣ 웹서버 환경 구축 ◈ JNLP 파일은 웹서버의 MIME에 등록되어 있지 않다. ◈ 아파치와 IIS 서버에. jnlp 확장자의 MIME 타입만 등록하면 된다. ▣ 아파치 웹서버의. jnlp 확장자의 MIME 지정 ◈ mime. types 설정 파일에 다음의 한 줄을 추가시켜 주면 된다. ◈ application/x-java-jnlp-file JNLP ▣ IIS 웹서버의. jnlp 확장자의 MIME 지정 ◈ ◈ ◈ ▣ IIS 관리자의 [기본 웹사이트]의 [등록정보]을 연다 [HTTP 헤더]를 열고 MIME 매핑 부분의 [파일 형식]을 클릭한다. 새로운 형식 추가를 위해 [새형식]을 클릭한다. [연결된 확장자명]에는 application/x-java-jnlp-file을 넣어준다. [컨텐츠 형식]에는 jnlp를 넣어준다. tomcat은. jnlp 확장자를 자동으로 지원 ◈ tomcat은 기본적으로 세팅(tomcat/conf/web. xml)이 되어 있습니다. ◈ jnlpapplication/x-java-jnlp-file 3/19/2018

14. 5. 6 단계 5 : 톰캣에서 가상 디렉터리 지정 ▣ [톰캣설치디렉터리]confserver. xml 파일 14. 5. 6 단계 5 : 톰캣에서 가상 디렉터리 지정 ▣ [톰캣설치디렉터리]confserver. xml 파일 수정 ◈ ◈ ◈ ◈ ▣ . . . 생략 server. xml . . . 생략 톰캣의 웹 애플리케이션이 되려면 1. 가상 디렉터리 설정을 한다. 2. Web-Inf 디렉터리 하위에 web. xml을 생성한다. 웹애플리케이션을 위한 web. xml 파일 생성 c: javasrcchap 14Web-Inf 디렉터리 생성 ◈ c: javasrcchap 14Web-Infweb. xml 생성 ◈ – web. xml은 RootWeb-Infweb. xml을 복사해서 사용하면 된다. 3/19/2018 web. xml

14. 5. 7 단계 6 : jnlp 파일 수정하기 ▣ ▣ ▣ ▣ ▣ 14. 5. 7 단계 6 : jnlp 파일 수정하기 ▣ ▣ ▣ ▣ ▣ Hello Java Web Start Application 2 JABOOK Hello Java Web Start Application 2 3/19/2018

14. 5. 8 단계 7 : Html 파일 작성 및 실행 ▣ hello-jws. html 14. 5. 8 단계 7 : Html 파일 작성 및 실행 ▣ hello-jws. html ◈ ◈ ◈ ▣ Hello Java Web Start 웹서버에 배포할 파일들 ◈ ◈ ◈ hello-jws. jar hello 2. jnlp hello-jws. html http: //localhost: 8080/jws/hellowebstart/hello-jws. html 클릭 3/19/2018

14. 5. 9 자바 웹 스타트 콘솔 3/19/2018 14. 5. 9 자바 웹 스타트 콘솔 3/19/2018

14. 6 Resource에 접근하기 3/19/2018 14. 6 Resource에 접근하기 3/19/2018

14. 6. 1 Resource에 접근하기 Java Web Start Architecture Resource 접근하기 Client 요청 1 14. 6. 1 Resource에 접근하기 Java Web Start Architecture Resource 접근하기 Client 요청 1 JNLP 페이지 요청 JNLP 페이지 다운로드 2 1. 분석 4. 프로그램 실행 2. 요청 3. 다운로드 3 Application 파일 요청 Application(jar 파일) 다운로드 4 class 파일 이미지 파일 5. jar 파일에서 이미지 얻기 6. 이미지 그리기 Javatm Web Start Client 3/19/2018 필요시 요청 jar 파일 Web Application Server

14. 6. 2 이미지 그리기 애플리케이션 ▣ ▣ ▣ ▣ ▣ ▣ ▣ public 14. 6. 2 이미지 그리기 애플리케이션 ▣ ▣ ▣ ▣ ▣ ▣ ▣ public class JWSImage. Frame extends Frame implements Action. Listener{ private Image img = null; private Button b 1 = new Button("누르세요"); public JWSImage. Frame(){ 컴파일과 압축파일 묶기(이미지디렉터리 포함) this. set. Layout(new Flow. Layout()); this. add(b 1); javac JWSImage. Frame. java this. b 1. add. Action. Listener(this); jar -cvf image-jws. jar *. class images/ } public void paint(Graphics g){ if(img != null){ g. draw. Image(img, 20, 100, this); } g. draw. String("Hello Web Start", 100, 70); } public void action. Performed(Action. Event e){ Class. Loader cl = this. get. Class(). get. Class. Loader(); java. net. URL url = cl. get. Resource("images/splash. jpg"); img = Toolkit. get. Default. Toolkit(). create. Image(url); Media. Tracker tracker = new Media. Tracker(this); tracker. add. Image(img, 0); try{ tracker. wait. For. ID(0); }catch(Interrupted. Exception e 2){e 2. print. Stack. Trace(); } repaint(); } public static void main(String[] args){/*. . 생략*/} } 3/19/2018

14. 6. 3 jnlp 파일 생성 및 실행 ▣ ▣ ▣ ▣ ▣ <? 14. 6. 3 jnlp 파일 생성 및 실행 ▣ ▣ ▣ ▣ ▣ 리소스 사용하기 Application JABOOK 리소스 사용하기 Application http: //localhost: 8080/jws/imagewebstart/image. jnlp URL로 직접 직접 접근해도 된다. 3/19/2018

14. 7 Java Web Start API 3/19/2018 14. 7 Java Web Start API 3/19/2018

14. 7. 1 JNLP Package API ▣ JNLP 패키지란 ◈ Sand. Box의 보안 제한 14. 7. 1 JNLP Package API ▣ JNLP 패키지란 ◈ Sand. Box의 보안 제한 구역 내에서 사용할 수 있는 API ◈ 클라이언트의 자원을 제한적으로 사용할 수 있게 해주는 API ▣ JNLP Package 파일들 ◈ 자바 5. 0과 자바 6. 0에서는 sample 디렉터리에 JNLP에 관련된 jnlp. jar, jnlp-servlet. jar, jardiff. jar 파 일이 포함되어 있다. – [자바설치디렉터리]samplejnlp ◈ [자바설치디렉터리]jrelibjavaws. jar 파일을 이용해도 된다. ▣ JNLP Package 클래스들 ◈ ◈ ◈ ◈ ▣ Basic. Service Clipboard. Service Download. Service File. Open. Service File. Save. Service Print. Service Persistence. Service File. Contents JNLP 패키지 import ◈ import javax. jnlp. *; 3/19/2018 이 파일을 [자바설치디렉터리]jrelibext에 복사한다.

14. 7. 2 Basic. Service ▣ Basic. Service ◈ Basic. Service는 JWS에서의 간단한 정보나 14. 7. 2 Basic. Service ▣ Basic. Service ◈ Basic. Service는 JWS에서의 간단한 정보나 브라우저를 제어하기 위한 API를 제공 ◈ 애플리케이션의 codebase URL이나 웹브라우저를 특정 URL로 보내기 위해서 사용 ▣ Basic. Service 사용하기 ◈ public class Basic. JWSFrame extends Frame implements Action. Listener{ ◈ private Button b 1 = new Button("웹브라우저 띄우기"); ◈ public Basic. JWSFrame(){ ◈ //. . . 생략 ◈ } 웹브라우저 띄우기 ◈ public void action. Performed(Action. Event e){ ◈ try{ ◈ Basic. Service bs = null; ◈ bs = (Basic. Service)Service. Manager. lookup("javax. jnlp. Basic. Service"); ◈ bs. show. Document(new URL("http: //www. jabook. org")); ◈ } ◈ catch(Exception e 2){e 2. print. Stack. Trace(); } ◈ public static void main(String[] args){ ◈ //. . . 생략 ◈ } 참고(codebase얻기) ◈ } URL url = bs. get. Code. Base() 3/19/2018

14. 7. 3 Clipboard. Service ▣ Clipboard. Service ◈ 클립보드에 객체를 복사하거나 가져오는 서비스를 14. 7. 3 Clipboard. Service ▣ Clipboard. Service ◈ 클립보드에 객체를 복사하거나 가져오는 서비스를 제공하는 클래스 ◈ JWS는 이 기능을 사용할 때 보안을 위하여 경고창을 보여준다. ▣ 클립보드 사용하기 ◈ public class Clipboard. JWSFrame extends Frame implements Action. Listener{ ◈ private Button b 1 = new Button("클립보드로 데이터 넣고 빼기"); ◈ //. . 생략 ◈ public void action. Performed(Action. Event e){ ◈ try{ ◈ Clipboard. Service cs; 1. Clipboard. Service 생성 ◈ cs = (Clipboard. Service)Service. Manager. lookup("javax. jnlp. Clipboard. Service"); ◈ ◈ 2. 클립보드에 문자열 복사하기 ◈ Transferable tr = cs. get. Contents(); if (tr. is. Data. Flavor. Supported(Data. Flavor. string. Flavor)) { String s = (String)tr. get. Transfer. Data(Data. Flavor. string. Flavor); System. out. println("Clipboard 내용: " + s); } }catch(Exception e 2){e 2. print. Stack. Trace(); } } //. . . 생략 3/19/2018 } ◈ ◈ 3클립보드로부터 데이터 가져오기 ◈ ◈ ◈ ◈ String. Selection ss = new String. Selection("Clipboard Babo!"); cs. set. Contents(ss);

14. 7. 4 Download. Service ▣ Download. Service ◈ ▣ Download. Service는 리소스를 캐시에 14. 7. 4 Download. Service ▣ Download. Service ◈ ▣ Download. Service는 리소스를 캐시에 저장, 삭제 등 캐시를 통제할 수 있는 서비스 API를 제공하는 클레스이다. Download. Service 사용하기 ◈ ◈ ◈ ◈ ◈ public class Download. JWSFrame extends Frame implements Action. Listener{ private Button b 1 = new Button("캐시확인하기"); public void action. Performed(Action. Event e){ try{ Basic. Service bs = null; bs = (Basic. Service)Service. Manager. lookup("javax. jnlp. Basic. Service"); 1. Download. Service 생성 2. 캐시 확인후 삭제 ◈ ◈ ◈ ◈ 3. 캐시로 로딩하기 } } //. . . 생략 3/19/2018 Download. Service ds; ds = (Download. Service)Service. Manager. lookup("javax. jnlp. Download. Service"); URL url = new URL(bs. get. Code. Base(), "downimage. jar"); boolean cached = ds. is. Resource. Cached(url, null); if (cached) { System. out. println("캐시 삭제"); ds. remove. Resource(url, null); }else{ System. out. println("캐시에 없음"); } Download. Service. Listener dsl = ds. get. Default. Progress. Window(); ds. load. Resource(url, null, dsl); System. out. println("캐시 로드"); }catch(Exception e 2){e 2. print. Stack. Trace(); }

14. 7. 5 File. Open. Service & File. Save. Service ▣ File. Open. Service 14. 7. 5 File. Open. Service & File. Save. Service ▣ File. Open. Service & File. Save. Service ◈ File. Open. Service는 Sand. Box 환경에서 파일 Open을 사용자에게 알리고 파일을 열 수 있는 다이얼 로그 윈도우를 띄우는 서비스 ◈ File. Save. Service는 Sand. Box 환경에서 파일 Save를 사용자에게 알리고 파일을 저장할 수 있는 다 이얼로그 윈도우를 띄우는 서비스 ▣ File. Open. Service & File. Save. Service의 사용 ◈ public class File. JWSFrame extends Frame implements Action. Listener{ ◈ private Button b 1 = new Button("File 서비스"); ◈ public void action. Performed(Action. Event e){ ◈ try{ ◈ File. Open. Service fos; ◈ fos = (File. Open. Service)Service. Manager. lookup("javax. jnlp. File. Open. Service"); ◈ File. Contents fc = fos. open. File. Dialog(null, null); ◈ //File. Contents[] fcs = fos. open. Multi. File. Dialog(null, null); 1. 파일 열기 ◈ ◈ 2. 파일저장하기 ◈ 파일 복사 File. Save. Service fss; fss = (File. Save. Service)Service. Manager. lookup("javax. jnlp. File. Save. Service"); ◈ File. Contents newfc = fss. save. File. Dialog(null, fc. get. Input. Stream(), null); ◈ //File. Contents newfc 2 = fss. save. As. File. Dialog(null, fc); ◈ }catch(Exception e 2){e 2. print. Stack. Trace(); } ◈ //. . . 생략 ◈ } 3/19/2018

Print. Service 14. 7. 6 Print. Service § Print. Service는 Sand. Box 환경하에서 프린트를 Print. Service 14. 7. 6 Print. Service § Print. Service는 Sand. Box 환경하에서 프린트를 가능하게 해주는 API 를 갖고 있는 서비스 클래스 § Print. Service를 이용해서 프린트를 요청하면 사용자에게 프린 트 허용여부를 묻는 보안 경과창이 나타난다. ▣ ▣ ▣ ▣ ▣ ▣ ▣ public class Print. JWSFrame extends Frame implements Action. Listener, Printable{ private Button b 1 = new Button("Print 하기"); public int print(Graphics g, Page. Format pf, int pi){ if (pi >= 1) { return Printable. NO_SUCH_PAGE; } Graphics 2 D g 2 = (Graphics 2 D) g; g 2. translate(pf. get. Imageable. X(), pf. get. Imageable. Y()); Image img = load. Image("images/splash. jpg"); if(img != null){ g 2. draw. Image(img, 100, this); } return Printable. PAGE_EXISTS; } public void action. Performed(Action. Event e){ try{ Print. Service ps = (Print. Service)Service. Manager. lookup("javax. jnlp. Print. Service"); Page. Format pf = ps. get. Default. Page(); Page. Format new. Pf = ps. show. Page. Format. Dialog(pf); ps. print(this); private Image load. Image(String img. File){ Image img = null; }catch(Exception e 2){e 2. print. Stack. Trace(); } Basic. Service bs = null; } try{ private Image load. Image(String img. File){ bs = (Basic. Service)Service. Manager. lookup("javax. jnlp. Basic. Service"); URL url = new URL(bs. get. Code. Base(), img. File); img = Toolkit. get. Default. Toolkit(). create. Image(url); Media. Tracker tracker = new Media. Tracker(this); tracker. add. Image(img, 0); tracker. wait. For. ID(0); }catch(Exception e){e. print. Stack. Trace(); } return img; } //. . . 생략 } 3/19/2018 }

14. 7. 7 Persistence. Service ▣ public class Persistence. JWSFrame extends Frame implements Action. 14. 7. 7 Persistence. Service ▣ public class Persistence. JWSFrame extends Frame implements Action. Listener{ ▣ private Button b 1 = new Button("상태관리 서비스"); ▣ public void action. Performed(Action. Event e){ ▣ try{ ▣ 1. Persistence. Service 생성 Persistence. Service ps = (Persistence. Service)Service. Manager. lookup("javax. jnlp. Persistence. Service"); ▣ ▣ URL url = new URL("http: //localhost: 8080/jws/"); 2. http: //localhost: 8080/jws/로 시작하는 하위 엔트리를 배열로 얻어낸다. ▣ String[] ar. Str = ps. get. Names(url); ▣ ▣ boolean exists = false; ▣ for(int i=0; i

14. 8 Signed Application 3/19/2018 14. 8 Signed Application 3/19/2018

14. 8. 1 자바 보안 모델 ▣ 보안 입장에서의 애플리케이션 Local Code ◈ Trusted 14. 8. 1 자바 보안 모델 ▣ 보안 입장에서의 애플리케이션 Local Code ◈ Trusted Remote Code ◈ Non-Trusted Remote Code ◈ Sand. Box는 Remote Code의 보안제한구역 Local Code 시스템에서 허용하는 모든 자원사용가능 Trusted Remote Code 인증필요 허가된 자원만 사용가능 JVM 3/19/2018 Non-Trusted Remote Code Sand. Box를 벗어날 수 없다. Sand. Box

14. 8. 2 Sand. Box의 보안 ▣ Remote Code의 보안 제한 ◈ ▣ Sand. 14. 8. 2 Sand. Box의 보안 ▣ Remote Code의 보안 제한 ◈ ▣ Sand. Box란 ◈ ▣ 애플릿이나 JWS의 경우 클라이언트에서 다운로드된 후 실행되는 프로그램이기 때 문에 보안상으로 제한할 필요가 있다. 프로그램의 무결성 및 시스템의 보안을 위한 보안 제한 구역이다. Sand. Box의 제한 사항 ◈ IO – 로컬의 IO(read/write)를 할 수 없다. (파일 접근 불가) ◈ 네트워크 – 애플리케이션은 자신이 다운로드된 서버와만 통신할 수 있다. ◈ 프로세스 – 로컬의 다른 프로그램을 실행시킬 수 없다. ◈ 스레드 – 자신이 소유하지 않은 스레드의 상태를 바꿀 수 없다. ◈ 시스템 프로퍼티 – 시스템 프로퍼티를 읽을 수 없다. (제한된 시스템 프로퍼티에 대해 읽는 것만 가능) ◈ 신뢰정책 – 신뢰정책을 결정하는 Security. Manager을 재설정할 수 없다. ◈ Native 메서드 – Native 메서드를 정의할 수 없다. 3/19/2018

14. 8. 3 단계 1 : Application 작성 ▣ ▣ ▣ ▣ ▣ public 14. 8. 3 단계 1 : Application 작성 ▣ ▣ ▣ ▣ ▣ public class Signed. JWSFrame extends Frame implements Action. Listener{ private Button b 1 = new Button("로컬에 파일 기록하기"); public Signed. JWSFrame(){ //. . . 생략 } public void action. Performed(Action. Event e){ try{ File. Writer fw = new File. Writer("c: \a. txt"); fw. write("안녕하세요rn"); fw. write("웹스타트에서 로컬 파일에 데이터를 기록합니다. rn"); fw. write("이만rn"); 로컬 자원에 접근(인증 필요) fw. close(); }catch(Exception e 2){e 2. print. Stack. Trace(); } } public static void main(String[] args){ Frame f = new Signed. JWSFrame(); f. set. Size(300, 100); f. set. Visible(true); } } 3/19/2018

14. 8. 4 단계 2 : jnlp 작성 ▣ ▣ ▣ <? xml version= 14. 8. 4 단계 2 : jnlp 작성 ▣ ▣ ▣ Signed Application 테스트 JABOOK Signed Application 테스트 ▣ ▣ ▣ 인증을 하지 않고 실행했을 때의 에러 3/19/2018

14. 8. 5 단계 3 : Signed Application 만들기 ▣ step 1 : JWS 14. 8. 5 단계 3 : Signed Application 만들기 ▣ step 1 : JWS 애플리케이션 jar 파일로 묶기 ◈ jar cvf signed-jws. jar *. class – – – ▣ keytool -genkey -keystore babokeystore -alias babokey – – – – – ▣ 추가된 manifest 추가 중: Signed. JWSFrame$1. class(내부 = 514) (외부= 344)(33%가 감소되었습니다. ) 추가 중: Signed. JWSFrame. class(내부 = 1609) (외부= 1015)(36%가 감소되었습니다. ) step 2 : 새로운 암호화 키 생성 ◈ 서명전 signed_jws. jar 파일 크기 : 1, 972 바이트 keystore 이름 : babokeystore key이름 : babokey keystore 암호를 입력하십시오: ks 1234 새 암호를 다시 입력하십시오: ks 1234 이름과 성을 입력하십시오. [Unknown]: Young-Kwan Choi 조직 단위 이름을 입력하십시오. 참고 [Unknown]: Novel. Java 조직 이름을 입력하십시오. jar. exe와 keytool. exe 그리고 jarsigner. exe는 자바 설치디렉터리 하위의 bin 디렉터리에 있다. [Unknown]: www. jabook. org 구/군/시 이름을 입력하십시오? [Unknown]: Kwang-Gin 시/도 이름을 입력하십시오. [Unknown]: Seoul 이 조직의 두 자리 국가 코드를 입력하십시오. [Unknown]: 82 CN=Young-Kwan Choi, OU=Novel. Java, O=www. jabook. org, L=Kwang-Gin, ST=Seoul, C=82 이(가) 맞습니까? [아니오]: y 에 대한 키 암호를 입력하십시오. key 1234 (keystore 암호와 같은 경우 Enter를 누르십시오): 새 암호를 다시 입력하십시오: key 1234 step 3 : Key. Store에 생성된 키를 이용해서 jar 파일 서명 ◈ jarsigner -keystore babokeystore signed-jws. jar babokey – – 3/19/2018 Enter Passphrase for keystore: ks 1234 Enter key password for babokey: key 1234 Warning: The signer certificate will expire within six months. 서명후 signed_jws. jar 파일 크기 : 3, 364 바이트

14. 8. 6 단계 4 : jnlp 파일 실행하기 1 1 -1 2 1 14. 8. 6 단계 4 : jnlp 파일 실행하기 1 1 -1 2 1 -2 c: a. txt 3 3/19/2018

14. 8. 7 배치파일 ▣ compile-run. bat 1. 2. 3. 4. del babokeystore del 14. 8. 7 배치파일 ▣ compile-run. bat 1. 2. 3. 4. del babokeystore del *. jar 1. keystore와 jar 파일 삭제 javac *. java jar -cvf signed-jws. jar *. class 2. 컴파일한 후 jar로 묶기 5. keytool -genkey -keystore babokeystore -alias babokey -dname "CN=Young. Kwan Choi, OU=Novel. Java, O=www. jabook. org, L=Kwang-Gin, ST=Seoul, C=82" -keypass key 1234 -storepass ks 1234 3. keystore 생성(private 키, public 키, 인증서) 6. jarsigner -keystore babokeystore -keypass key 1234 -storepass ks 1234 signed 4 jar파일에 서명하기 jws. jar babokey 7. "C: Program FilesInternet ExplorerIEXPLORE. EXE" http: //localhost: 8080/jws/signed-jws. jnlp 3/19/2018 5. 웹브라우저에서 jnlp 파일 실행하기

14. 9 Java Web Start 자동 설치 3/19/2018 14. 9 Java Web Start 자동 설치 3/19/2018

14. 9. 1 브라우저 종류에 따른 JWS 설치 확인하 기 ▣ ▣ ▣ ▣ 14. 9. 1 브라우저 종류에 따른 JWS 설치 확인하 기 ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ If Not(Is. Object(Create. Object("Java. Web. Start. is. Installed. 1. 6. 0. 0"))) 3/19/2018

if" src="https://present5.com/presentation/631f7ff7028da29774af0c03b7a7f94b/image-52.jpg" alt="14. 9. 2 방법 1 : Sun에서 제공하는 사이트 이용 3/19/2018

14. 9. 3 방법 2 : 자동 다운로드 Active. X를 이용 ▣ ▣ <HTML> 14. 9. 3 방법 2 : 자동 다운로드 Active. X를 이용 ▣ ▣ 1. 4. 0 : http: //java. sun. com/products/plugin/autodl/jinstall-1_4_0 -win. cab 1. 5. 0 : http: //java. sun. com/update/1. 5. 0/jinstall-1_5_0 -windows-i 586. cab 1. 6. 0 : http: //java. sun. com/update/1. 6. 0/jinstall-6 -windows-i 586. cab 버전에 따라 이 부분만 변경하면 된다. ▣ ▣ ▣ ▣ 설치되어 있으면 app의 경로를 실행 Download Java Web Start ▣ ▣ ▣ 설치되어 있지 않으면 설치 메시지를 보여준다. 3/19/2018

15 ██████ 15 3/19/2018 15 ██████ 15 3/19/2018

15장 자바 Database 소설같은 3 자바 rd Edition since 2001 최영관 Powered by http: 15장 자바 Database 소설같은 3 자바 rd Edition since 2001 최영관 Powered by http: //www. jabook. org 3/19/2018

15. 1 JDBC의 기본 3/19/2018 15. 1 JDBC의 기본 3/19/2018

15. 1. 1 JDBC란 ▣ public Lcorp. Monitor implements IMonitor{ public void power(boolean flag){ 15. 1. 1 JDBC란 ▣ public Lcorp. Monitor implements IMonitor{ public void power(boolean flag){ //L사에 맞게 구현 } } S사의 모니터 ◈ ◈ ◈ ▣ public Hcorp. Monitor implements IMonitor{ public void power(boolean flag){ //H사에 맞게 구현 } } L사의 모니터 ◈ ◈ ◈ ▣ public interface IMonitor{ void power(boolean flag); } JDBC와 DATABASE H사의 모니터 ◈ ◈ ◈ ▣ JDBC란 데이터베이스에 연결 및 작업을 하기 위한 자바 표준 인터페이스이다. 국내에서 모니터를 판매하기 위해서는 반드시 IMonitor 인터페이스를 구현해서 만들어야 한다. ◈ ◈ ◈ ▣ 드라이브의 역할을 한다. JDBC(Java Data. Base Connectivity) ◈ ▣ JDBC 인터페이스와 동일한 역할을 한다. public Scorp. Monitor implements IMonitor{ public void power(boolean flag){ //S사에 맞게 구현 } } Java 응용 프로그램 표준인터페이스가 없다면 자바 프로그램에서 각각의 데이터베이스에 연결하는 방법이 달라진다. 프로그래머는 하나의 인터페이스로 모든 데이터베이스에 연결할 수 있다. 데이터페이스 표준 인터페이스 JDBC 벤더마다 DBMS가 다르기 때문에 각 회사에서 Driver를 제작한다. Oracle Driver My. SQL Driver MS SQL Driver Oracle My. SQL MS SQL IMonitor로 모든 모니터를 제어 ◈ ◈ ◈ IMonitor h = new Hcorp. Monitor(); h. power(true); h. power(false); IMonitor l = new Lcorp. Monitor(); l. power(true); l. power(false); 프로그래머는 드라이브를 이용해서 메서드를 호출한다. IMonitor s = Scorp. Monitor(); s. power(true); s. power(false); 3/19/2018

15. 1. 2 JDBC Driver의 종류 Java 응용 프로그램 JDBC Driver. Manager JDBC-ODBC bridge 15. 1. 2 JDBC Driver의 종류 Java 응용 프로그램 JDBC Driver. Manager JDBC-ODBC bridge Native-API 드라이버 Network 프로토콜 드라이버 ODBC Driver Native Library Web App 서버 미들웨어 DBMS Type 1 Type 2 Type 3 Type 4 JDBC-ODBC 브리지 드라이버(Type 1) Native API 드라이버(Type 2) 네트워크 프로토콜 드라이버 (Type 3) DBMS 프로토콜 드라이버(Type 4) C 언어 기반인 ODBC 드라이버를 연결 해주는 역할만 하는 드라이버로 Java SDK에 기본적으로 포함된 sun. jdbc. odbc. Jdbc. Odbc. Driver가 이에 속한다. C, C++등으로 만들어진 Native Library를 호출하여 DB에 연결 하는 드라이버로서 해당하는 C, C++ Native API를 설치해야 사 용할 수 있다. JDBC 호출을 네트워크 프로토콜로 바꾸어 미들웨어에 전달하여 DB 작 업을 처리하게 하는 드라이버로 순수 자바로 만들어져 있다. 순수 자바로 만들어졌으며, DBMS를 직접 호출하는 드라이버로 JDBC 드 라이버와 데이터베이스간의 1: 1 관계 를 가진다. 현재 가장 많이 쓰이는 드 라이버이다. 3/19/2018 DBMS프로토콜 드라이버

15. 2 MS-SQL Server 2000 3/19/2018 15. 2 MS-SQL Server 2000 3/19/2018

15. 2. 1 MS-SQL Server 2000 Driver 등록 ▣ MS-SQL Server 2000용 JDBC 드라이버를 15. 2. 1 MS-SQL Server 2000 Driver 등록 ▣ MS-SQL Server 2000용 JDBC 드라이버를 다운로드(SP 3용) ◈ http: //www. microsoft. com/ ▣ 디폴트 설치 디렉터리 ◈ c: Program FilesMicrosoft SQL Server 2000 Driver for JDBC ▣ 필요한 JDBC 드라이버 패키지 ◈ c: Program FilesMicrosoft SQL Server 2000 Driver for JDBClibmsbase. jar ◈ c: Program FilesMicrosoft SQL Server 2000 Driver for JDBClibmsutil. jar ◈ c: Program FilesMicrosoft SQL Server 2000 Driver for JDBClibmssqlserver. jar ▣ 튜토리얼 파일 ◈ c: Program FilesMicrosoft SQL Server 2000 Driver for JDBCbooksMsjdbcref. pdf ▣ 클래스 패스 지정 ◈ 3개의 파일을 jar 파일을 [자바 설치 디렉터리]jrelibext 디렉터리에 두면 자동으로 클래스 패스 가 지정된다. ▣ MS-SQL Server 2000 드라이버 로딩 ◈ Class. for. Name("com. microsoft. jdbc. sqlserver. SQLServer. Driver"); ▣ Driver. Manager를 이용한 드라이버 로딩 ◈ Driver. Manager. register. Drivers(new com. microsoft. jdbc. sqlserver. SQLServer. Driver()); 3/19/2018

15. 2. 2 MS-SQL Server DB 세팅 새로운 데이터베이스 생성을 위한 속성 지정 새로운 15. 2. 2 MS-SQL Server DB 세팅 새로운 데이터베이스 생성을 위한 속성 지정 새로운 데이터베이스 생성 새로 생성된 데이터베이스 3/19/2018

15. 2. 3 MS-SQL Server User 생성 1 2 3 4 6 5 3/19/2018 15. 2. 3 MS-SQL Server User 생성 1 2 3 4 6 5 3/19/2018 새로 생성된 계정 7

15. 2. 4 MS-SQL Server Hello Database ▣ ▣ ▣ ▣ ▣ import java. 15. 2. 4 MS-SQL Server Hello Database ▣ ▣ ▣ ▣ ▣ import java. sql. *; public class Hello. Selector{ public static void main(String[] args) throws Class. Not. Found. Exception, SQLException{ JDBC Class. for. Name("com. microsoft. jdbc. sqlserver. SQLServer. Driver"); 드라이브로딩 String url = "jdbc: microsoft: sqlserver: //localhost: 1433; database=javadb"; String id = "javadbo"; DB 연결 URL String pass = "javadbo"; Connection conn = Driver. Manager. get. Connection(url, id, pass); 얻어내기 Statement stmt = conn. create. Statement(); 생성 Statement Result. Set rs = stmt. execute. Query("select * from My. Hello"); 생성 while(rs. next()){ System. out. print(rs. get. String("name") + " "); System. out. println(rs. get. Int("age")); } rs. close(); stmt. close(); conn. close(); } } 3/19/2018

15. 3 JDBC-ODBC Driver 3/19/2018 15. 3 JDBC-ODBC Driver 3/19/2018

15. 3. 1 JDBC-ODBC Driver 세팅 3/19/2018 15. 3. 1 JDBC-ODBC Driver 세팅 3/19/2018

15. 3. 2 ODBC DSN 생성 1 2 5 3 7 4 6 3/19/2018 15. 3. 2 ODBC DSN 생성 1 2 5 3 7 4 6 3/19/2018

15. 3. 3 JDBC-ODBC Hello Database ▣ ▣ ▣ ▣ ▣ import java. sql. 15. 3. 3 JDBC-ODBC Hello Database ▣ ▣ ▣ ▣ ▣ import java. sql. *; public class Odbc. Selector{ public static void main(String[] args) throws Class. Not. Found. Exception, SQLException{ Class. for. Name("sun. jdbc. odbc. Jdbc. Odbc. Driver"); JDBC 드라이브로딩 String url = "jdbc: odbc: javadsn"; URL DB 연결 String id = "javadbo"; JDBC-ODBC String pass = "javadbo"; Connection conn = Driver. Manager. get. Connection(url, id, pass); Statement stmt = conn. create. Statement(); Result. Set rs = stmt. execute. Query("select * from My. Hello"); while(rs. next()){ System. out. print(rs. get. String("name") + " "); System. out. println(rs. get. Int("age")); } rs. close(); stmt. close(); conn. close(); } } 3/19/2018

15. 4 기타 JDBC 드라이버 연결 3/19/2018 15. 4 기타 JDBC 드라이버 연결 3/19/2018

15. 4. 1 MS-SQL Server 2005 Driver 1. 1 ▣ MS-SQL Server 2005용 JDBC 15. 4. 1 MS-SQL Server 2005 Driver 1. 1 ▣ MS-SQL Server 2005용 JDBC 드라이버를 다운로드 ◈ ▣ http: //www. microsoft. com/ JDBC 드라이버 패키지 파일 다운된 파일은 압축 파일 형태로 되어 있으며 압축을 해제한 후 사용하면 된다. ◈ [압축해제디렉터리]sqljdbc. jar ◈ ▣ 튜토리얼 파일 ◈ ▣ [압축해제디렉터리]helpdefault. htm 클래스 패스 지정 ◈ sqljdbc. jar 파일을 [자바 설치 디렉터리]jrelibext 디렉터리에 두면 자동으로 클래스 패스가 지정된다. Class. for. Name("com. microsoft. jdbc. sqlserver. SQLServer. Driver"); ▣ MS-SQL Server 2005 드라이버 로딩 ◈ ▣ Class. for. Name("com. microsoft. sqlserver. jdbc. SQLServer. Driver"); 2000과 2005의 차이점 MS-SQL Server 2005 URL ◈ String url = "jdbc: sqlserver: //localhost: 1433; database=javadb"; 3/19/2018 String url = "jdbc: microsoft: sqlserver: //localhost: 1433; database=javadb";

15. 4. 2 My. SQL Connector/J 5. x ▣ My. SQL 다운로드 사이트 ◈ 15. 4. 2 My. SQL Connector/J 5. x ▣ My. SQL 다운로드 사이트 ◈ ▣ JDBC 드라이버 패키지 파일 ◈ ◈ ▣ mysql-connector-java-5. x. x-bin. jar 파일을 [자바 설치 디렉터리]jrelibext 디렉터리 에 두면 자동으로 클래스 패스가 지정된다. My. SQL Connector/J 5. x 드라이버 로딩 ◈ ▣ [압축해제디렉터리]docsconnector-j. html 클래스 패스 지정 ◈ ▣ Connector/J 5. x라는 이름으로 등록되어 있으며 zip 또는 tar 파일 형태로 묶여 있다. 압축해제디렉터리mysql-connector-java-5. x. x-bin. jar 튜토리얼 파일 ◈ ▣ http: //www. mysql. com Class. for. Name("com. mysql. jdbc. Driver"); My. SQL JDBC Driver My. SQL Connector/J 5. x URL ◈ String url = "jdbc: mysql: //localhost: 1099/javadb"; 서버명 3/19/2018 포트 데이터베이스 이름

15. 5 JDBC 기본 클래스 3/19/2018 15. 5 JDBC 기본 클래스 3/19/2018

15. 5. 1 Connection ▣ Connection 순서 ◈ ◈ ▣ 1. 드라이버 로딩 ◈ 15. 5. 1 Connection ▣ Connection 순서 ◈ ◈ ▣ 1. 드라이버 로딩 ◈ ▣ 쿼리와 명령 처리 4. Connection 닫기 ◈ ▣ String url = "jdbc: microsoft: sqlserver: //localhost: 1433; database=javadb"; String id = "javadbo"; String pass = "javadbo"; Connection conn = Driver. Manager. get. Connection(url, id, pass); 3. 작업 ◈ ▣ Class. for. Name("com. microsoft. jdbc. sqlserver. SQLServer. Driver"); 2. Driver. Manager를 이용해서 Connection 객체 생성 ◈ ◈ ▣ 1. Class. for. Name()으로 드라이버 로딩 2. Driver. Manager의 get. Connection()을 이용해서 Connection 객체 생성 3. 필요한 작업 4. 연결 종료 : Connection close() conn. close(); Connection의 속성값들 ◈ ◈ ◈ Database. Name : 접속하려는 SQL 서버의 데이터베이스명 User : 사용자의 이름 Password : 사용자의 비밀번호 Port. Number : TCP 포트번호. 기본값은 1443 Server. Name : 연결하려는 SQL 서버가 위치하고 있는 IP 주소 3/19/2018 Connection

15. 5. 2 Statement ▣ ▣ ▣ ▣ ▣ import java. sql. *; public 15. 5. 2 Statement ▣ ▣ ▣ ▣ ▣ import java. sql. *; public class Hello. Inserter{ //main()의 매개변수 //args[0] : 이름 //args[1] : 나이 public static void main(String[] args) throws Class. Not. Found. Exception, SQLException{ Class. for. Name("com. microsoft. jdbc. sqlserver. SQLServer. Driver"); String url = "jdbc: microsoft: sqlserver: //localhost: 1433; database=javadb"; String id = "javadbo"; String pass = "javadbo"; Connection conn = Driver. Manager. get. Connection(url, id, pass); Statement stmt = conn. create. Statement(); String sql = "insert into My. Hello values('" +args[0]+ "', " +args[1]+ ")"; int r = stmt. execute. Update(sql); Statement System. out. println(r + " 데이터 삽입 OK" ); stmt. close(); conn. close(); } } 3/19/2018

15. 5. 3 Result. Set ▣ ▣ ▣ ▣ ▣ import java. sql. *; 15. 5. 3 Result. Set ▣ ▣ ▣ ▣ ▣ import java. sql. *; public class Hello. Selector{ public static void main(String[] args) throws Class. Not. Found. Exception, SQLException{ Class. for. Name("com. microsoft. jdbc. sqlserver. SQLServer. Driver"); String url = "jdbc: microsoft: sqlserver: //localhost: 1433; database=javadb"; String id = "javadbo"; String pass = "javadbo"; Connection conn = Driver. Manager. get. Connection(url, id, pass); Statement stmt = conn. create. Statement(); Result. Set rs = stmt. execute. Query("select * from My. Hello"); while(rs. next()){ System. out. print(rs. get. String("name") + " "); Result. Set System. out. println(rs. get. Int("age")); } rs. close(); stmt. close(); conn. close(); } } 3/19/2018

15. 6 데이터베이스 Query 처리 3/19/2018 15. 6 데이터베이스 Query 처리 3/19/2018

15. 6. 1 Statement ▣ 스테이트먼트의 종류 ◈ ◈ ◈ ▣ Statement ◈ ▣ 15. 6. 1 Statement ▣ 스테이트먼트의 종류 ◈ ◈ ◈ ▣ Statement ◈ ▣ 하나의 Prepared. Statement로 쿼리를 여러 번 처리할 수 있다. 스테이트먼트의 의미 ◈ ▣ 하나의 쿼리를 사용하고 나면 더이상 사용할 수 없다. Prepared. Statement ◈ ▣ Statement Prepared. Statement Callable. Statement 자바에서 사용되는 3가지 종류의 스테이트먼트들은 데이터베이스로 쿼리를 담아서 보내는 그릇 정도로 생각하면 된다. 즉 스테이트먼트에 쿼리를 실어 데이터베이스로 보내버리면 데이터베이스에서 처리되는 것이다. 이 때 한번 사용하고 버리는 그릇은 Statement이며, 재사용 가능한 그릇은 Prepared. Statement이다. Callable. Statement ◈ 데이터베이스 내의 스토어드 프로시저(Stored Procedure)를 호출할 수 있는 스테이트 먼트 3/19/2018

15. 6. 2 Prepared. Statement ▣ ▣ ▣ Class. for. Name( 15. 6. 2 Prepared. Statement ▣ ▣ ▣ Class. for. Name("com. microsoft. jdbc. sqlserver. SQLServer. Driver"); String url = "jdbc: microsoft: sqlserver: //localhost: 1433; database=javadb"; String id = "javadbo"; String pass = "javadbo"; Connection conn = Driver. Manager. get. Connection(url, id, pass); ▣ ▣ String sql = "insert into My. Hello (name, age) values (? , ? )"; Prepared. Statement pstmt = conn. prepare. Statement(sql); ▣ ▣ ▣ pstmt. set. String(1, "변강쇠"); pstmt. set. Int(2, 20); pstmt. execute. Update(); ▣ ▣ ▣ pstmt. set. String(1, "어사또"); pstmt. set. Int(2, 50); pstmt. execute. Update(); ▣ ▣ ▣ pstmt. set. String(1, "월매"); pstmt. set. Int(2, 50); pstmt. execute. Update(); ▣ ▣ ▣ pstmt. set. String(1, "방자"); pstmt. set. Int(2, 25); pstmt. execute. Update(); ▣ ▣ ▣ pstmt. set. String(1, "향단이"); pstmt. set. Int(2, 15); pstmt. execute. Update(); ▣ ▣ pstmt. close(); conn. close(); 3/19/2018 Prepare. Statement의 매개변수 지정 Prepared. Statement를 이용 해서 반복적으로 명령 실행하기

15. 6. 3 Callable. Statement-Return ▣ 스토어드 프로시저(Stored Procedure) ◈ ▣ 데이터베이스 내에서 사용되어지는 15. 6. 3 Callable. Statement-Return ▣ 스토어드 프로시저(Stored Procedure) ◈ ▣ 데이터베이스 내에서 사용되어지는 함수 Callable. Statement의 특징 ◈ ◈ 데이터베이스의 스토어드 프로시저를 실행시킬 때 사용 속도, 코드의 독립성, 보안성에 상당한 이점이 있음. Stored Procedure 예 CREATE PROCEDURE [javadbo]. [sp_get. Age. Selector] @find. Person varchar(20), @n. Age int OUTPUT AS SELECT @n. Age = age FROM My. Hello Where name = @find. Person ▣ Callable. Statement의 생성 ◈ ◈ ▣ 출력용 반환 타입 세팅 ◈ ▣ Callable. Statement cs = conn. prepare. Call("{call sp_get. Age. Selector(? , ? )}"); 2번째 결과를 출력용으로 세팅 ◈ ▣ cs. register. Out. Parameter(2, java. sql. Types. INTEGER); Callable. Statement 생성 ◈ ▣ Callable. Statement cs = conn. prepare. Call("{call sp_get. Age. Selector(? , ? )}"); cs. set. String(1, "홍길동"); cs. register. Out. Parameter(2, java. sql. Types. INTEGER); Stored. Procedure 실행 ◈ ◈ cs. execute(); cs. get. Int(2) 3/19/2018

3/19/2018 3/19/2018

15. 6. 4 Callable. Statement-Result. Set ▣ 동적으로 스토어드 프로시저 생성하기 //Connection conn이 존재한다고 15. 6. 4 Callable. Statement-Result. Set ▣ 동적으로 스토어드 프로시저 생성하기 //Connection conn이 존재한다고 가정 ◈ Statement stmt = conn. create. Statement(); ◈ stmt. execute. Update("CREATE PROCEDURE [javadbo]. [sp_get. Result. Set] as SELECT * FROM My. Hello"); ◈ stmt. close(); ◈ ▣ 스토어드 프로시저 호출하기 ◈ ◈ ◈ Callable. Statement cs = conn. prepare. Call("{call sp_get. Result. Set}"); Result. Set rs = cs. execute. Query(); Statement stmt = conn. create. Statement(); stmt. execute. Update("CREATE PROCEDURE [javadbo]. [sp_get. Result. Set] as SELECT * FROM My. Hello"); stmt. close(); 3/19/2018

15. 6. 5 Transaction 처리 ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ 15. 6. 5 Transaction 처리 ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ Class. for. Name("com. microsoft. jdbc. sqlserver. SQLServer. Driver "); String url = "jdbc: microsoft: sqlserver: //203. 252. 134. 119: 1433"; String id = "javadbo"; String pass = "javadbo"; Connection conn = null; Prepared. Statement pstmt; try{ conn = Driver. Manager. get. Connection(url, id, pass); conn. set. Auto. Commit(false); //트랙젝션 가능 pstmt = conn. prepare. Statement("insert into My. Hello (name, age) values (? , ? )"); varchar(20)) 3/19/2018 pstmt. set. String(1, "트랜잭션"); //1. 데이터 삽입 pstmt. set. Int(2, 50); pstmt. execute. Update(); System. out. println("Data Inserted 1"); pstmt. set. String(1, "abcdefghijklmnopqrstuvwxyz"); //2. 데이터 삽입(에러발생 name은 길이는 pstmt. set. Int(2, 50); pstmt. execute. Update(); System. out. println("Data Inserted 2"); conn. commit(); //3. COMMIT 수행 System. out. println("COMMIT Complete 2!"); }catch(SQLException e){ if(conn != null){ try{ conn. rollback(); //3. ROLLBACK 수행 System. out. println("ROLLBACK Complete!"); }catch(SQLException e 2){e. print. Stack. Trace(); } } }finally{ try{ //4. 데이터베이스 닫기 conn. set. Auto. Commit(true); pstmt. close(); conn. close(); }catch(SQLException e 3){e 3. print. Stack. Trace(); } }

15. 7 데이터베이스 고급기법 3/19/2018 15. 7 데이터베이스 고급기법 3/19/2018

15. 7. 1 개요 ▣ 데이터베이스의 처리 속도 ◈ ▣ 컨넥션 풀링(Connection Pooling) ◈ 15. 7. 1 개요 ▣ 데이터베이스의 처리 속도 ◈ ▣ 컨넥션 풀링(Connection Pooling) ◈ ▣ 데이터베이스의 처리에서 가장 많은 시간을 필요로 하는 부분은 데 이터베이스의 로그인 부분이다. 프로그래밍 시작할 때 미리 컨넥션(Connection)을 여러 개 개설한 뒤 필요할 때 만들어 둔 컨넥션을 사용하는 기법 JDBC 사용의 고급기법 Connection Factory 기법 ◈ Connection Pooling 기법 ◈ 3/19/2018

15. 7. 2 Connection Factory 기법 Connection Factory 2 Connection 생성 Conn. Factory 클래스 15. 7. 2 Connection Factory 기법 Connection Factory 2 Connection 생성 Conn. Factory 클래스 사용자 프로그램 1 Connection 요구 create. Connection() Connection 필요 Conn. Factory의 생성자와 멤버 ◈ ◈ ◈ ▣ ▣ ▣ private Conn. Factory(){ } public static Conn. Factory get. Default. Factory(){ }; public Connection create. Connection(){ }; Conn. Factory conn. Fac = Conn. Factory. get. Default. Factory(); Conn. Factory로부터 Connection 얻어내기 ◈ Connection conn = conn. Fac. create. Connection(); 3/19/2018 MS SQL Mysql 싱글톤(Singleton) 기법으로 Conn. Factory 얻어내기 ◈ Connection (Connection 생성) 3 Connection 제공 ▣ Oracle 컨넥션 공장(Connection Factory)을 구현하기 위한 Conn. Factory 클래스 ◈ public class Conn. Factory { ◈ private static Conn. Factory conn. Factory = new Conn. Factory(); ◈ private Conn. Factory(){}; ◈ public static Conn. Factory get. Default. Factory(){ ◈ if(conn. Factory == null){ ◈ conn. Factory = new Conn. Factory(); ◈ } ◈ return conn. Factory; ◈ } ◈ public Connection create. Connection(){. . . } ◈ }

15. 7. 3 Properties 클래스 ▣ Properties에 데이터를 삽입하는 방법 ◈ ◈ ◈ ▣ 15. 7. 3 Properties 클래스 ▣ Properties에 데이터를 삽입하는 방법 ◈ ◈ ◈ ▣ Properties p를 파일로 저장하기 ◈ ◈ ▣ Properties p = new Properties(); File. Input. Stream in = new File. Input. Stream("jdbc. properties"); p. load(in); in. close(); Properties p에 있는 데이터 얻어내기 ◈ ◈ ◈ ▣ File. Output. Stream out = new File. Output. Stream("jdbc. properties"); p. store(out, "JDBC Config Setting"); out. close(); # 표시로 시작하면 주석으로 처리된다. 파일의 데이터를 Properties p로 로딩하기 ◈ ◈ ▣ Properties p = new Properties(); p. put("Driver", "sun. jdbc. odbc. Jdbc. Odbc. Driver"); p. put("URL", "jdbc: odbc: javadsn"); p. set. Property("Max. Conn", "10"); p. set. Property("User", "javadbo"); p. set. Property("Password", "javadbo"); System. out. println(p. get. Property("Driver")); System. out. println(p. get. Property("URL")); System. out. println(p. get. Property("Max. Conn")); System. out. println(p. get. Property("User")); System. out. println(p. get. Property("Password")); Properties p에 들어 있는 데이터를 콘솔로 출력하기 3/19/2018 ◈ p. list(System. out);

15. 7. 4 Connection Factory의 구현 ▣ ▣ ▣ ▣ ▣ public class Conn. 15. 7. 4 Connection Factory의 구현 ▣ ▣ ▣ ▣ ▣ public class Conn. Factory{ public static Conn. Factory get. Default. Factory(){ private static int maxconn = 0; if(conn. Factory == null){ private static String url = null; conn. Factory = new Conn. Factory(); private static String driver = null; } private static String user = null; return conn. Factory; private static String password = null; } private static Conn. Factory conn. Factory = new Conn. Factory(); static{ try{ load. Properties("jdbc. properties"); }catch(IOException e){ public System. out. println("jdbc. properties Connection create. Connection() throws SQLException, Class. Not. Found. Exception{. . . "); Class. for. Name(driver); e. print. Stack. Trace(); Connection conn = Driver. Manager. get. Connection(url, user, password); } return conn; } } private Conn. Factory(){}; public static Conn. Factory get. Default. Factory(){ ▣ ▣ ▣ } public Connection create. Connection() throws SQLException, Class. Not. Found. Exception{ ▣ ▣ } public static void load. Properties(String filename) throws IOException{ ▣ ▣ ▣ } } public static int get. Max. Conn(){ return maxconn; } 3/19/2018 public static void load. Properties(String filename) throws IOException{ Properties p = new Properties(); File. Input. Stream in = new File. Input. Stream(filename); p. load(in); in. close(); url = p. get. Property("url"); driver = p. get. Property("driver"); user = p. get. Property("user"); password = p. get. Property("password"); maxconn = Integer. parse. Int(p. get. Property("maxconn")); }

15. 7. 5 Connection Factory 테스트 ▣ ▣ ▣ ▣ ▣ import org. jabook. 15. 7. 5 Connection Factory 테스트 ▣ ▣ ▣ ▣ ▣ import org. jabook. Conn. Factory; import java. sql. *; public class Conn. Factory. Main{ Conn. Factory의 사용 public static void main(String[] args) throws SQLException, Class. Not. Found. Exception{ Conn. Factory factory = Conn. Factory. get. Default. Factory(); Connection conn = factory. create. Connection(); Statement stmt = conn. create. Statement(); Result. Set rs = stmt. execute. Query("SELECT * FROM My. Hello"); while(rs. next()){ System. out. print(rs. get. String("name")); System. out. println(rs. get. Int("age")); } rs. close(); stmt. close(); conn. close(); } } 3/19/2018

15. 7. 6 Connection Pooling이란 ▣ Connection Pooling 기법 ◈ 미리 컨넥션을 일정 수만큼 15. 7. 6 Connection Pooling이란 ▣ Connection Pooling 기법 ◈ 미리 컨넥션을 일정 수만큼 생성시킨 뒤 컨넥션을 빌려주고 다시 반환받는 형식으로 컨넥션을 관리한다. ◈ 컨넥션 풀에서 필요한 만큼 Connection을 미리 생성 ◈ Connection이 필요할 때 컨넥션 풀에서 빌려서 사용 ◈ 사용이 끝난 다음에는 Connection을 컨넥션 풀에 반환 ▣ Connection Pooling 기법의 장점 ◈ Connection Pooling 기법을 이용하면 데이터베이스에 연결하는 시간을 절약할 수 있다. Connection Pooling Connection Pool에 남아 있는Connection이 있다면 get. Connection()으로 Pool에서 Conneciton을 빌린다. 사용자 프로그램 Connection conn … … 2 conn의 사용 … … … release. Connection(conn) 3/19/2018 Connection 1 Connection 요청 Connection Pool get. Connection() Connection release. Connection(conn) Connection 3 Connection 반환 빌린 Connection을 release. Connection()으로 반환한다. create. Connection() Conn. Factory Connection Pool에서 미리 정해진 개수의 Connection을 Conn. Factory 를 이용해서 개설한다.

15. 7. 7 Connection Pooling의 구조 ▣ Conn. Pool을 싱글톤(Singleton) 방식으로 노출 ◈ ◈ 15. 7. 7 Connection Pooling의 구조 ▣ Conn. Pool을 싱글톤(Singleton) 방식으로 노출 ◈ ◈ ◈ ◈ ◈ ▣ ▣ ▣ public class Conn. Pool{ private static Conn. Pool conn. Pool = new Conn. Pool(); private Conn. Pool(){/*private 디폴트 생성자*/} public static Conn. Pool get. Conn. Pool(){ if(conn. Pool == null){ conn. Pool = new Conn. Pool(); } return conn. Pool; } } ▣ Conn. Pool을 이용해서 Connection을 얻어내고 작업을 한 후 다시 반납하기 ◈ Conn. Pool pool = Conn. Pool. get. Conn. Pool(); ◈ Connection conn = pool. get. Connection(); ◈ //작업(conn을 이용해서 데이터베이스 작업) ◈ pool. release. Connection(conn); ◈ public static void init. Conn. Pool() throws SQLException, Class. Not. Found. Exception{. . . } ◈ public synchronized static void destroy. Conn. Pool(){. . . } ◈ private Vector get. Conn. Pool. Buffer(){. . . } ▣ Conn. Pool의 전체구조 ◈ public class Conn. Pool{ ◈ private Vector buffer = new Vector(); ◈ private static Conn. Pool conn. Pool = new Conn. Pool(); 싱글톤(Singleton) 방식으로 Conn. Pool 얻어내기 ◈ private Conn. Pool(){/*private 디폴트 생성자*/} ◈ Conn. Pool pool = Conn. Pool. get. Conn. Pool(); ◈ public static Conn. Pool get. Conn. Pool(){ ◈ if(conn. Pool == null){ Connection의 저장공간 ◈ conn. Pool = new Conn. Pool(); ◈ private Vector buffer = new Vector(); ◈ } ◈ public synchronized Connection get. Connection() throws Interrupted. Exception(){. . . }◈ return conn. Pool; ◈ public synchronized void release. Connection(Connection conn){. . . } ◈ public static void init. Conn. Pool() ◈ throws SQLException, Class. Not. Found. Exception{. . . } Conn. Pool의 구조 ◈ public synchronized static void destroy. Conn. Pool(){. . . } ◈ public class Conn. Pool{ ◈ ◈ private Vector buffer = new Vector(); ◈ public synchronized Connection get. Connection() throws Interrupted. Exception{. . . } ◈ private static Conn. Pool conn. Pool = new Conn. Pool(); ◈ public synchronized void release. Connection(Connection conn){. . . } ◈ private Conn. Pool(){/*private 디폴트 생성자*/} ◈ private Vector get. Conn. Pool. Buffer(){. . . } ◈ public static Conn. Pool get. Conn. Pool(){ ◈ ◈ ◈ ◈ if(conn. Pool == null){ conn. Pool = new Conn. Pool(); } return conn. Pool; ◈ } public synchronized Connection get. Connection() throws Interrupted. Exception(){. } public synchronized void release. Connection(Connection conn){. . . } } 3/19/2018 }

15. 7. 8 Connection Pooling 구현 ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ 15. 7. 8 Connection Pooling 구현 ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ ▣ public class Conn. Pool{ ▣ private Vector buffer = new Vector(); ▣ private static Conn. Pool conn. Pool = new Conn. Pool(); ▣ static{ ▣ try{ ▣ init. Conn. Pool(); ▣ }catch(SQLException e){ ▣ System. out. println("---Connection Create ▣ Error---"); ▣ e. print. Stack. Trace(); ▣ }catch(Class. Not. Found. Exception e 2){ ▣ System. out. println("---Driver Calss Not ▣ Found Error--"); ▣ e 2. print. Stack. Trace(); ▣ } ▣ private Conn. Pool(){/*private 디폴트 생성자*/} ▣ public static void init. Conn. Pool() throws SQLException, Class. Not. Found. Exception{ factory. create. Connection(); ▣ ▣ ▣ destroy. Conn. Pool(); Vector temp = Conn. Pool. get. Conn. Pool(). get. Conn. Pool. Buffer(); Conn. Factory factory = Conn. Factory. get. Default. Factory(); for(int i=0; i

15. 7. 9 Connection Pooling 테스트 ▣ ▣ ▣ ▣ ▣ import org. jabook. 15. 7. 9 Connection Pooling 테스트 ▣ ▣ ▣ ▣ ▣ import org. jabook. Conn. Factory; import org. jabook. Conn. Pool; import java. sql. *; public class Conn. Pool. Main{ public static void main(String[] args) throws SQLException, Interrupted. Exception{ Conn. Pool pool = Conn. Pool. get. Conn. Pool(); Connection conn = pool. get. Connection(); Statement stmt = conn. create. Statement(); Result. Set rs = stmt. execute. Query("SELECT * FROM My. Hello"); while(rs. next()){ System. out. print(rs. get. String("name")); System. out. println(rs. get. Int("age")); } rs. close(); stmt. close(); pool. release. Connection(conn); //Conn. Pool. destroy. Conn. Pool(); } } 3/19/2018

16 ██████ 16 3/19/2018 16 ██████ 16 3/19/2018

16장 자바 Network 소설같은 3 자바 rd Edition since 2001 최영관 Powered by http: 16장 자바 Network 소설같은 3 자바 rd Edition since 2001 최영관 Powered by http: //www. jabook. org 3/19/2018

16. 1 네트워크의 기본 프로그램 3/19/2018 16. 1 네트워크의 기본 프로그램 3/19/2018

16. 1. 1 개요 ▣ 자바의 네트워크의 예 애플릿의 동작원리 ◈ IO에서의 네트워크 지원 16. 1. 1 개요 ▣ 자바의 네트워크의 예 애플릿의 동작원리 ◈ IO에서의 네트워크 지원 ◈ ▣ 자바와 네트워크 ◈ ▣ 네트워크 기능을 강화한 언어가 자바 언어이다. java. net 패키지 내의 대표적인 기본 클래스들 ◈ ◈ ◈ URL 클래스 Inet. Address 클래스 URLConnection 클래스 URLDecoder 클래스 URLEncoder 클래스 URLClass. Loader 클래스 3/19/2018

16. 1. 2 URL 클래스 ▣ ▣ ▣ ▣ ▣ import java. net. *; 16. 1. 2 URL 클래스 ▣ ▣ ▣ ▣ ▣ import java. net. *; import java. io. *; public class URLMain{ public static void main(String args[]) throws Malformed. URLException, IOException{ URL url = new URL("http: //www. jabook. org: 80/index. html"); System. out. println("Port: " + url. get. Port()); System. out. println("Protocol: " + url. get. Protocol()); System. out. println("Host. Name: " + url. get. Host()); System. out. println("File: " + url. get. File()); System. out. println("Ref: " + url. get. Ref()); String temp; Buffered. Reader br; br = new Buffered. Reader(new Input. Stream. Reader(url. open. Stream())); while ((temp = br. read. Line()) != null) { System. out. println(temp); } br. close(); } } 3/19/2018

16. 1. 3 Inet. Address 클래스 ▣ Inet. Address 객체를 생성하는 방법 ◈ ◈ 16. 1. 3 Inet. Address 클래스 ▣ Inet. Address 객체를 생성하는 방법 ◈ ◈ ◈ ◈ ◈ ▣ Inet. Address 클래스의 get. Host. Name()와 get. Host. Address() ◈ ◈ ◈ ◈ ▣ import java. net. *; public class Inet. Address. Main{ public static void main(String[] args) throws Unknown. Host. Exception{ Inet. Address inet 1 = Inet. Address. get. By. Name("www. jabook. org"); Inet. Address inet 2 = Inet. Address. get. By. Name("203. 252. 134. 117"); System. out. println(inet 1); System. out. println(inet 2); } } import java. net. *; public class Inet. Address. Main 2{ public static void main(String[] args) throws Unknown. Host. Exception{ Inet. Address inet = Inet. Address. get. By. Name("www. jabook. org"); System. out. println(inet. get. Host. Name()); System. out. println(inet. get. Host. Address()); } } Inet. Address 클래스의 get. Local. Host() ◈ ◈ ◈ ◈ import java. net. *; public class Inet. Address. Main 3{ public static void main(String[] args) throws Unknown. Host. Exception{ Inet. Address inet = Inet. Address. get. Local. Host(); System. out. println(inet. get. Host. Name()); System. out. println(inet. get. Host. Address()); } } 3/19/2018

16. 1. 4 URLConnection 클래스 ▣ ▣ ▣ ▣ ▣ ▣ import java. net. 16. 1. 4 URLConnection 클래스 ▣ ▣ ▣ ▣ ▣ ▣ import java. net. *; import java. io. *; public class URLConnection. Main 2{ public static void main(String args[]) throws Malformed. URLException, IOException{ URL url = new URL("http: //onesearch. sun. com/search/onesearch/index. jsp"); URLConnection conn = url. open. Connection(); conn. set. Do. Output(true); Output. Stream os = conn. get. Output. Stream(); Print. Writer out = new Print. Writer(os); out. println("qt=love"); out. close(); String temp; Input. Stream is = conn. get. Input. Stream(); Input. Stream. Reader isr = new Input. Stream. Reader(is); Buffered. Reader br = new Buffered. Reader(isr); while( (temp=br. read. Line())!=null){ System. out. println(temp); } br. close(); } } 3/19/2018 출력 스트림 제어 입력 스트림 제어

16. 1. 5 URLEncoder와 URLDecoder ▣ ▣ import java. io. *; import java. net. 16. 1. 5 URLEncoder와 URLDecoder ▣ ▣ import java. io. *; import java. net. *; public class URLEn. Decoder. Main{ public static void main(String [] args) throws Unsupported. Encoding. Exception{ String en. Str = URLEncoder. encode("소설 같은_자바-www. jabook. org", ▣ "EUC_KR"); URLEncoder의 사용 System. out. println("인코딩된 문자열: " + en. Str); ▣ URLDecoder의 사용 ▣ String de. Str = URLDecoder. decode(en. Str, "EUC_KR"); ▣ System. out. println("디코딩된 문자열: " + de. Str); } ▣ ▣ } 3/19/2018

16. 1. 6 URLClass. Loader 클래스 ▣ URLClass. Loader를 이용한 클래스 로딩 ◈ ◈ 16. 1. 6 URLClass. Loader 클래스 ▣ URLClass. Loader를 이용한 클래스 로딩 ◈ ◈ ◈ ◈ ◈ ▣ public class URLClass. Loader. Main{ public static void main(String[] args) throws Malformed. URLException, Class. Not. Found. Exception, Instantiation. Exception, Illegal. Access. Exception{ URL[] ar. URL = {new File("c: /javasrc/chap 16/"). to. URL()}; URLClass. Loader ucl = new URLClass. Loader(ar. URL); Class c = ucl. load. Class("Hello"); Object obj = c. new. Instance(); URLClass. Loader의 사용 System. out. println(obj. to. String()); } } URLClass. Loader의 get. Resource. As. Stream()을 이용해서 리소스(파일) 읽기 ◈ ◈ ◈ ◈ public class URLClass. Loader. Main 2{ public static void main(String[] args) throws Malformed. URLException, Class. Not. Found. Exception, Instantiation. Exception, Illegal. Access. Exception, IOException{ URL[] ar. URL = {new File("c: /javasrc/chap 16/"). to. URL()}; URLClass. Loader ucl = new URLClass. Loader(ar. URL); Input. Stream is = ucl. get. Resource. As. Stream("Hello. java"); Input. Stream. Reader isr = new Input. Stream. Reader(is); int c; while( (c = isr. read()) != -1 ){ URLClass. Loader의 System. out. print((char)c); } get. Resource. As. Stream()의 사용 isr. close(); } } 3/19/2018

16. 2 Socket의 기본 3/19/2018 16. 2 Socket의 기본 3/19/2018

16. 2. 1 소켓통신의 기본 ▣ 소켓(Socket)이란 ◈ ▣ 네트워크로 연결된 두 대의 호스트간에 16. 2. 1 소켓통신의 기본 ▣ 소켓(Socket)이란 ◈ ▣ 네트워크로 연결된 두 대의 호스트간에 통신을 위한 양쪽 끝을 의미한다. 소켓(Socket)의 역할 ◈ 컨넥션(Connection)을 개설하기 위한 도구 – 전화기나 무전기정도로 생각하면 된다. ▣ 대표적 Well Known Port ◈ ◈ ◈ 7 : Echo 13 : Day. Time 21 : Ftp 23 : Telnet 25 : SMTP 80 : HTTP 3/19/2018

16. 2. 2 TCP와 UDP 통신 TCP 통신의 개념 Client Server TCP Socket Port 16. 2. 2 TCP와 UDP 통신 TCP 통신의 개념 Client Server TCP Socket Port 3456 IP: 203. 252. 134. 117 TCP Requst Port Accept Socket 8080 IP: 203. 252. 134. 101 양방향 통신 UDP 통신의 개념 Client Send Port Datagram. Packet Receive Port Datagram. Socket 3456 IP: 203. 252. 134. 117 Server 8080 IP: 203. 252. 134. 101 Missing 3/19/2018

16. 3 TCP Client Programming 3/19/2018 16. 3 TCP Client Programming 3/19/2018

16. 3. 1 Echo Client Program ▣ ▣ ▣ ▣ ▣ public class Echo. 16. 3. 1 Echo Client Program ▣ ▣ ▣ ▣ ▣ public class Echo. Client. Main{ //main()에 세 개의 매개변수가 필요 //args[0] : 에코서버주소 //args[1] : 에코서버포트 //args[2] : 공백없는 메시지 //java Echo. Client. Main 202. 30. 38. 101 7 Hello_World public static void main(String[] args) throws IOException { Socket socket = new Socket(args[0], Integer. parse. Int(args[1])); Socket생성 Buffered. Reader br; br = new Buffered. Reader(new Input. Stream. Reader(socket. get. Input. Stream())); ▣ Print. Writer pw = new Print. Writer(socket. get. Output. Stream(), true); ▣ 데이터보내기 ▣ 데이터읽기 String reply = br. read. Line(); //응답 받기 스트림닫기 System. out. print("Echo: " + reply); br. close(); pw. close(); socket. close(); ▣ ▣ ▣ 소켓닫기 } } 3/19/2018 pw. println(args[2]); //데이터 보내기 입력 스트림생성 출력스트림생성

16. 3. 2 Day. Time Client Program ▣ ▣ ▣ ▣ import java. io. 16. 3. 2 Day. Time Client Program ▣ ▣ ▣ ▣ import java. io. *; import java. net. *; public class Day. Time. Client. Main{ //main()에 두 개의 매개변수가 필요 //args[0] : Day. Time서버주소 //args[1] : Day. Time서버포트 public static void main(String[] args) throws IOException { Socket socket = new Socket(args[0], Integer. parse. Int(args[1])); ▣ ▣ ▣ 입력 스트림생성 ▣ ▣ 데이터읽기 ▣ ▣ 스트림과 소켓닫기 ▣ ▣ } } 3/19/2018 Socket생성 Buffered. Reader br; br = new Buffered. Reader(new Input. Stream. Reader(socket. get. Input. Stream())); String reply. Time = br. read. Line(); //서버로부터 시간 받기 System. out. print(args[0] + " Server Time: " + reply. Time); br. close(); socket. close();

16. 3. 3 HTTP Client Program-Socket I ▣ ▣ public class Http. Client. Main{ 16. 3. 3 HTTP Client Program-Socket I ▣ ▣ public class Http. Client. Main{ public static void main(String[] args) throws IOException { ▣ Socket생성 ▣ ▣ ▣ ▣ ▣ 입출력 스트림생성 데이터보내기 데이터 읽어서 파 일에 기록하기 } } 3/19/2018 Socket socket = new Socket(args[0], Integer. parse. Int(args[1])); Buffered. Input. Stream bis = new Buffered. Input. Stream(socket. get. Input. Stream()); Print. Writer out = new Print. Writer(socket. get. Output. Stream()); out. print("GET /index. html HTTP/1. 0rn"); out. print("rn"); out. flush(); File. Output. Stream fs = new File. Output. Stream(args[2]); Buffered. Output. Stream bos = new Buffered. Output. Stream(fs); int c; while( (c = bis. read()) != -1 ){ bos. write(c); } out. close(); bis. close(); bos. close(); socket. close(); 파일 스트림 개설 main()에 세 개의 매개변수가 필요 args[0] : 웹서버주소 args[1] : 웹서버포트 args[2] : 저장할 파일명

16. 3. 4 HTTP Client Program-Socket II ▣ ▣ public class Http. Client. Main 16. 3. 4 HTTP Client Program-Socket II ▣ ▣ public class Http. Client. Main 2{ public static void main(String[] args) throws IOException { ▣ Socket생성 ▣ ▣ ▣ ▣ ▣ 입출력 스트림생성 데이터보내기 데이터 읽어서 파 일에 기록하기 } } 3/19/2018 Socket socket = new Socket(args[0], Integer. parse. Int(args[1])); Buffered. Input. Stream bis = new Buffered. Input. Stream(socket. get. Input. Stream()); Print. Stream out = new Print. Stream(socket. get. Output. Stream()); out. print("GET /index. html HTTP/1. 1rn"); out. print("Host: " + args[0] + "rn"); out. print("rn"); out. flush(); File. Output. Stream fs = new File. Output. Stream(args[2]); Buffered. Output. Stream bos = new Buffered. Output. Stream(fs); int c; while( (c = bis. read()) != -1 ){ bos. write(c); } out. close(); bis. close(); bos. close(); socket. close(); 파일 스트림 개설 main()에 세 개의 매개변수가 필요 args[0] : 웹서버주소 args[1] : 웹서버포트 args[2] : 저장할 파일명

16. 3. 5 HTTP Client Program-URLConnection ▣ ▣ import java. io. *; import java. 16. 3. 5 HTTP Client Program-URLConnection ▣ ▣ import java. io. *; import java. net. *; public class Http. Client. Main 3{ public static void main(String[] args) throws IOException { ▣ main()에 두 개의 매개변수가 필요 args[0] : 웹서버주소 args[1] : 저장할 파일명 Http. URLConnection 객체 생성 ▣ URL url = new URL(args[0]); Http. URLConnection http. Conn = (Http. URLConnection)url. open. Connection(); Http. URLConnection 모드 설정 ▣ http. Conn. set. Request. Method("GET"); ▣ 입력 스트림생성 Buffered. Input. Stream bis = new Buffered. Input. Stream(http. Conn. get. Input. Stream()); ▣ ▣ File. Output. Stream fs = new File. Output. Stream(args[1]); 파일 스트림 개설 Buffered. Output. Stream bos = new Buffered. Output. Stream(fs); ▣ ▣ int c; while( (c = bis. read()) != -1 ){ bos. write(c); } ▣ ▣ 데이터 읽어서 파 일에 기록하기 bis. close(); bos. close(); } } 3/19/2018

16. 3. 6 HTTP Client Program-URL ▣ ▣ import java. io. *; import java. 16. 3. 6 HTTP Client Program-URL ▣ ▣ import java. io. *; import java. net. *; public class Http. Client. Main 4{ public static void main(String[] args) throws IOException { main()에 두 개의 매개변수가 필요 args[0] : 웹서버주소 args[1] : 저장할 파일명 URL url = new URL(args[0]); Buffered. Input. Stream bis = new Buffered. Input. Stream(url. open. Stream()); ▣ URL을 이용한 스트림 개설 ▣ ▣ ▣ 파일 스트림 개설 File. Output. Stream fs = new File. Output. Stream(args[1]); Buffered. Output. Stream bos = new Buffered. Output. Stream(fs); ▣ ▣ int c; while( (c = bis. read()) != -1 ){ bos. write(c); } ▣ ▣ 데이터 읽어서 파 일에 기록하기 bis. close(); bos. close(); } } 3/19/2018

16. 4 TCP Echo Server & Client 3/19/2018 16. 4 TCP Echo Server & Client 3/19/2018

16. 4. 1 TCP Server. Socket의 동작 원리 Echo Clients Client 1 ☎ 2302 16. 4. 1 TCP Server. Socket의 동작 원리 Echo Clients Client 1 ☎ 2302 Echo Server Socket ☎ 3325 Client 2 Internet Socket ☎ 4567 Client 3 accept() 10000 Server. Socket ▣ Server. Socket ◈ ▣ Server. Socket의 생성과 접속 대기 ◈ ◈ ▣ Server. Socket ss = new Server. Socket(10000); Socket socket = ss. accept(); Server. Socket의 accept()에서 리턴된 서버용 Socket ◈ ◈ ◈ ▣ Server. Socket은 클라이언트와 통신할 수 있는 서버용 Socket을 만들어 준다. 클라이언트 Socket으로 Server. Socket에 연결요청할 때 accept()가 반응한다. Server. Socket이 accept()할 때 리턴된 서버용 Socket은 해당 클라이언트와 통신할 수 있는 유일한 수단이다. accept()할 때 리턴된 서버용 Socket은 자동으로 포트(Port)를 할당받는다. 서버용 Socket의 생성 및 스트림 개설 ◈ ◈ Server. Socket ss = new Server. Socket(10000); Socket socket = ss. accept(); Input. Stream is = socket. get. Input. Stream(); Output. Stream os = socket. get. Output. Stream(); 3/19/2018 ☎ ☎ ☎ Socket Client 1 4343 Client 2 4344 Client 3 4345

16. 4. 2 TCP Echo Server public class Echo. Server. Main{ public static void 16. 4. 2 TCP Echo Server public class Echo. Server. Main{ public static void main (String args[]) throws IOException{ Server. Socket생성 Server. Socket ss = new Server. Socket (Integer. parse. Int(args[0])); while (true) { 소켓 연결 대기 Socket socket = ss. accept(); System. out. println (new Date(). to. String() + ": " + socket. to. String()); Buffered. Reader br = new Buffered. Reader(new Input. Stream. Reader(socket. get. Input. Stream())); Buffered. Writer bw = new Buffered. Writer(new Output. Stream. Writer(socket. get. Output. Stream())); 메시지 읽기 입력 스트림으로 에코 연결된 소켓으로 입출력 스트림 생성 String temp = br. read. Line(); 출력 스트림으로 에코 메시지 내보내기 bw. write(temp + " 1n"); bw. flush(); bw. write(temp + " 2n"); bw. flush(); bw. write(temp + " 3n"); bw. flush(); 스트림닫기와 소켓 닫기 br. close(); bw. close(); socket. close(); } //ss. close(); } } 3/19/2018 main()에 한 개의 매개변수 피요 args[0] : 에코서버를 서비스할 포트

16. 4. 3 TCP Echo Client import java. io. *; import java. net. *; 16. 4. 3 TCP Echo Client import java. io. *; import java. net. *; import java. util. *; public class Echo. Client. Main 2{ public static void main (String args[]) throws IOException{ main()에 세 개의 매개변수가 필요 args[0] : 에코서버주소 args[1] : 에코서버포트 args[2] : 공백없는 메시지 Server. Socket생성 Socket socket = new Socket(args[0], Integer. parse. Int(args[1])); Buffered. Writer bw = new Buffered. Writer(new Output. Stream. Writer(socket. get. Output. Stream())); Buffered. Reader br = new Buffered. Reader(new Input. Stream. Reader(socket. get. Input. Stream())); 연결된 소켓으로 입출력 스트림 생성 bw. write(args[2] + "n"); 출력 스트림으로 에코 메시지 내보내기 bw. flush(); System. out. println(br. read. Line()); 입력 스트림으로 에코 메시지 읽기 System. out. println(br. read. Line()); br. close(); bw. close(); socket. close(); } } 3/19/2018

16. 4. 4 TCP Echo 테스트 3/19/2018 16. 4. 4 TCP Echo 테스트 3/19/2018

16. 5 UDP Echo Server & Client 3/19/2018 16. 5 UDP Echo Server & Client 3/19/2018

16. 5. 1 UDP 개요 - 구조 UDP 통신의 개념 A Computer Internet = 16. 5. 1 UDP 개요 - 구조 UDP 통신의 개념 A Computer Internet = 우체부 B Computer 203. 252. 134. 119 203. 252. 149. 33 0 터 : 200 컴퓨 터 내는 2. 149. 33 보 컴퓨 25 받는 : 3000 203. 119 134. 252. 203. 편지가 제대로 갔을까? Datagram. Socket Da Da ket 받는 컴퓨터 203. 252. 134. 119 : 3000 3/19/2018 ac am. P r ag Dat 203. 252. 134. 119 3000 번 ta ta 보내는 컴퓨터 203. 252. 149. 33 : 2000 편지가 왔을까? 203. 252. 149. 33 2000 번 Internet 우체함 확인 Datagram. Socket을 3000번 으로 개설한 뒤 데이터를 확 인해야 함.

16. 5. 2 UDP 개요 - B Computer public class UDP_B_Computer. Main{ public static 16. 5. 2 UDP 개요 - B Computer public class UDP_B_Computer. Main{ public static void main(String[] args) throws IOException{ 1. Datagram. Socket 생성 2. 데이터를 받을 Datagram. Packet 생성 Datagram. Socket udpsocket = new Datagram. Socket(Integer. parse. Int(args[0])); System. out. println("B Computer 3000 Port Waiting. . . "); byte[] buffer = new byte[1024]; Datagram. Packet recv. Pack = new Datagram. Packet(buffer, 1024); udpsocket. receive(recv. Pack); 데이터 받기 args[0]: Datagram. Socket을 개설할 로컬의 포트 java UDP_B_Computer. Main 3000 3. 받은 Datagram. Packet에서 정보 추출 4. 받은 Datagaram. Packet의 정보 출력 5. Datagram. Socket 닫기 } } 3/19/2018 Inet. Address client = recv. Pack. get. Address(); int client. Port = recv. Pack. get. Port(); int msg. Length = recv. Pack. get. Length(); byte[] msg. Bytes = recv. Pack. get. Data(); String msg. Recv = new String(msg. Bytes, 0, msg. Length); System. out. println("Sender: " + client + ": " + client. Port); System. out. println("Receiver: Localhost: " + args[0]); System. out. println("Receive Message: " + msg. Recv); System. out. println("Receive Time: " + new Date()); // udpsocket. close();

16. 5. 3 UDP 개요 - A Computer public class UDP_A_Computer. Main{ public static 16. 5. 3 UDP 개요 - A Computer public class UDP_A_Computer. Main{ public static void main(String[] args) throws IOException{ 1. Datagram. Socket 생성 Datagram. Socket udpsocket = new Datagram. Socket(Integer. parse. Int(args[0])); 2. 필요한 정보 만들기 Inet. Address client = Inet. Address. get. By. Name(args[1]); int client. Port = Integer. parse. Int(args[2]); int msg. Length = args[3]. length(); byte[] msg. Bytes = args[3]. get. Bytes(); Datagram. Packet send. Pack; send. Pack = new Datagram. Packet(msg. Bytes, msg. Length, client. Port); 3. 패킷 생성 udpsocket. send(send. Pack); System. out. println("Send Message: " + args[3]); System. out. println("Send Time: " + new Date()); 4. 패킷 전송 } } args[0]: Datagram. Socket을 개설할 로컬의 포트 args[1]: 받는 컴퓨터의 주소 args[2]: 받는 컴퓨터의 포트 args[3]: 전송할 메시지 java UDP_A_Computer. Main 2000 203. 252. 134. 119 3000 Hello_World 3/19/2018

16. 5. 4 UDP Echo Server public class UDPEcho. Server. Main{ public static void 16. 5. 4 UDP Echo Server public class UDPEcho. Server. Main{ public static void main(String[] args) throws IOException{ 1. Datagram. Socket 생성 main()의 매개변수 args[0]: Datagram. Socket을 개설할 로컬의 포 트 Datagram. Socket udpsocket = new Datagram. Socket(Integer. parse. Int(args[0])); byte[] buffer = new byte[1024]; Datagram. Packet recv. Pack = new Datagram. Packet(buffer, 1024); while(true){ 2. 데이터를 받기위한 Datagram. Packet 생성 3. 클라이언트로부터 데이터그램 받기 4. 받은 Datagram. Packet에서 정보 추출 5. 받은 Datagram. Packet의 정보 출력 6. 클라이언트로 메시지 보내기 } 3/19/2018 } udpsocket. receive(recv. Pack); Inet. Address client = recv. Pack. get. Address(); int client. Port = recv. Pack. get. Port(); int msg. Length = recv. Pack. get. Length(); byte[] msg. Bytes = recv. Pack. get. Data(); String msg. Recv = new String(msg. Bytes, 0, msg. Length); System. out. println("Sender: " + client + ": " + client. Port); System. out. println("Receiver: Localhost: " + args[0]); System. out. println("Receive Message: " + msg. Recv); System. out. println("Receive Time: " + new Date()); Datagram. Packet send. Pack; send. Pack = new Datagram. Packet(msg. Bytes, msg. Length, client. Port); udpsocket. send(send. Pack); String msg. Send = new String(msg. Bytes, 0, msg. Length); System. out. println("Send Message: " + msg. Send); System. out. println("Send Time: " + new Date() +"rn"); } //udpsocket. close();

16. 5. 5 UDP Echo Client public class UDPEcho. Client. Main{ public static void 16. 5. 5 UDP Echo Client public class UDPEcho. Client. Main{ public static void main(String[] args) throws IOException{ 1. 필요한 정보 만들기 Datagram. Socket udpsocket = new Datagram. Socket(Integer. parse. Int(args[0])); Inet. Address inet = Inet. Address. get. By. Name(args[1]); int port = Integer. parse. Int(args[2]); String send. Msg = new String(args[3]. to. String()); int len = send. Msg. length(); 2. UDP Echo Server로 메시지 전송 3. UDP Echo Server로부터 메시지 받기 4. 받은 Datagram. Packet에서 정보 추출 5. 받은 Datagram. Packet의 정보 출력 } 3/19/2018 } Datagram. Packet send. Pack; send. Pack = new Datagram. Packet(send. Msg. get. Bytes(), len, inet, port); udpsocket. send(send. Pack); System. out. println("Send Message: " + send. Msg); System. out. println("Send Time: " + new Date()); byte[] buffer = new byte[1024]; Datagram. Packet recv. Pack = new Datagram. Packet(buffer, 1024); udpsocket. receive(recv. Pack); Inet. Address client = recv. Pack. get. Address(); int client. Port = recv. Pack. get. Port(); String msg. Recv = new String(recv. Pack. get. Data(), 0, recv. Pack. get. Length()); // System. out. println("Sender: " + client + ": " + client. Port); System. out. println("Receiver: Localhost: " + args[0]); main()의 매개변수 System. out. println("Message: " + msg. Recv); System. out. println("Receive Time: " + new Date()); args[0]: Datagram. Socket을 개설할 로컬의 포트 udpsocket. close(); args[1]: 받는 컴퓨터의 주소 args[2]: 받는 컴퓨터의 포트 args[3]: 전송할 메시지

16. 5. 6 UDP Pushing ▣ UDP를 이용해서 특정 IP로 데이터를 Pushing ◈ ◈ 16. 5. 6 UDP Pushing ▣ UDP를 이용해서 특정 IP로 데이터를 Pushing ◈ ◈ ◈ ◈ ◈ ▣ public class UDPPushing. Server { public static void main(String[] args) throws Exception { Datagram. Socket socket = new Datagram. Socket(); Inet. Address inet = Inet. Address. get. By. Name(args[0]); int port = Integer. parse. Int(args[1]); System. out. println( args[0] + ": " + args[1] + "로 무조건 Pushing"); while(true){ String date. Str = new String(new Date(). to. String()+"rn"); int len = date. Str. length(); Datagram. Packet packet. Out; packet. Out = new Datagram. Packet(date. Str. get. Bytes(), len, inet, port); socket. send(packet. Out); System. out. print(" Sending: "+date. Str); Thread. sleep(1000); } } } main()의 매개변수 args[0] : Pushing할 주소 args[1] : Pushing할 포트 서버에서 Pushing한 데이터 받아내기 ◈ ◈ ◈ ◈ public class UDPPushing. Client { public static void main(String[] args) throws Exception { Datagram. Packet packet. In=null; byte packet. Buf[] = new byte[1024]; Datagram. Socket socket = new Datagram. Socket(Integer. parse. Int(args[0])); String day. Time; while(true){ packet. In = new Datagram. Packet(packet. Buf, 1024); socket. receive(packet. In); day. Time = new String(packet. In. get. Data(), 0, packet. In. get. Length()); System. out. print("Received: " + day. Time); } } } 3/19/2018 main()의 매개변수 args[0] : 데이터를 받을 포트

16. 6 TCP Chatting 3/19/2018 16. 6 TCP Chatting 3/19/2018

16. 6. 1 TCP Chatting의 동작 원리 Chatting Client 4 출력과 입력 스트림개설 ☎ 16. 6. 1 TCP Chatting의 동작 원리 Chatting Client 4 출력과 입력 스트림개설 ☎ Client 1 Chatting Server 5 2302 Socket 1 4 양방향통신 Socket 생성 및 접속 Internet accept() 10000 Server. Socket Client 5 Client 4 3/19/2018 Client 2 Client 3 2 접속요청을 받아들임 입력과 출력 스트림 개설 ☎ 3 Client 1 4343 accept()로 Socket생성 ☎ ☎ Client 2 4344 Client 3 4345

16. 6. 2 TCP Chatting의 메시지 전송 Chatting Client 1 ☎ 2302 Chat. Client 16. 6. 2 TCP Chatting의 메시지 전송 Chatting Client 1 ☎ 2302 Chat. Client Chatting Server 대기상태(스레드) 1 Socket 2 안녕하세요 Internet 필요할 때 전송 6 ▣ 안녕하세요 서버 프로그램 ◈ ◈ ◈ Chat. Server 클래스 Chat. Runner 클래스 Chat. Room 클래스 3/19/2018 ☎ 3 Client 1 4343 방검색 Chat. Room Chat. Runner 5 안녕하세요 6 다른 사람의 메시지 전송 ☎ 4 ☎ 4 안녕하세요 5 6 안녕하세요 Chat. Runner 5 안녕하세요 Chat. Runner 안녕하세요 모든 Chat. Runner는 Chat. Room에 등록 Chat. Runner 안녕하세요 ▣ 안녕하세요 클라이언트 프로그램 ◈ ◈ Chat. Client 클래스 Chat. Client. Main 클래스

16. 6. 3 TCP Chatting의 메시지 전송 순서 Chat. Client와 Chat. Runner의 메시지 전송 16. 6. 3 TCP Chatting의 메시지 전송 순서 Chat. Client와 Chat. Runner의 메시지 전송 Chatting Client Chatting Server Chat. Runner가 보내는 메시지 대기 ☎ Client 1 2302 Chat. Client가 보내는 메시지 대기 대기상태(스레드) 메시지가 도착하면 클라이언트 창에 표시한다. 대기상태(스레드) Internet 메시지 입력과 엔 터 그리고 전송 3/19/2018 메시지가 도착하면 모든 Chat. Client에 전송한다. Socket 필요할 때 전송 Chat. Runner 서버의 메시지 전송 ☎ Client 1 4343 다른 Chat. Client가 보낸 메시지 전송

16. 6. 4 TCP Chatting - Chat. Server import java. io. *; import java. 16. 6. 4 TCP Chatting - Chat. Server import java. io. *; import java. net. *; public class Chat. Server{ public static Chat. Room room = new Chat. Room(); public static void main(String[] args) throws IOException{ 2. 클라이언트 접속 대기 while(true){ Socket socket = s. Socket. accept(); System. out. println(socket + "입장"); Chat. Runner cr = new Chat. Runner(socket); 3. Chat. Runner 생성 Chat. Server. room. add. Chat. Runner(cr); cr. start(); //Chat. Runner 스레드 시작 4. Chat. Room에 Chat. Runner 추가 } } 3/19/2018 args[0] : 채팅서버의 포트 Server. Socket s. Socket = new Server. Socket(Integer. parse. Int(args[0])); System. out. println("채팅 서버 시작. . . "); 1. Server. Socket 생성 } main()의 매개변수

16. 6. 5 TCP Chatting - Chat. Room public class Chat. Room extends Vector{ 16. 6. 5 TCP Chatting - Chat. Room public class Chat. Room extends Vector{ Chat. Runner를 추가하는 메서드 Chat. Runner를 제거하는 메서드 모든 Chat. Runner에게 메시 지를 전송하는 메서드 } 3/19/2018 public synchronized void add. Chat. Runner(Object obj){ this. add. Element(obj); } public synchronized void remove. Chat. Runner(Object obj){ if(this. contains(obj)){ this. remove(obj); } } public synchronized void send. Msg. All(String msg){ Enumeration en = this. elements(); while(en. has. More. Elements()){ Chat. Runner c = (Chat. Runner)en. next. Element(); try{ c. send. Message(msg); }catch(IOException e){ System. out. println(c. to. String() + "의 메시지 전송 에러"); } } }

16. 6. 6 TCP Chatting - Chat. Runner public class Chat. Runner extends Thread{ 16. 6. 6 TCP Chatting - Chat. Runner public class Chat. Runner extends Thread{ private boolean flag = false; private Socket socket = null; private Buffered. Reader br = null; private Buffered. Writer bw = null; 생성자에서는 소켓을 이용해서 스트림 생성 public Chat. Runner(Socket socket) throws IOException{ this. socket = socket; br = new Buffered. Reader(new Input. Stream. Reader(socket. get. Input. Stream())); bw = new Buffered. Writer(new Output. Stream. Writer(socket. get. Output. Stream())); } public void run(){ try{ while(!this. flag){ String msg = br. read. Line(); if(msg != null && !msg. equals("")){ public void run(){ //. . . 메시지를 받고 받은 메시지를 전체 Chat. Runner에게 전송 } Chat. Server. room. send. Msg. All(msg); }else{ this. flag = true; } } Chat. Server. room. remove. Chat. Runner(this); br. close(); bw. close(); socket. close(); }catch(IOException e){e. print. Stack. Trace(); } public void send. Message(String msg) throws IOException{ this. bw. write(msg + "n"); 클라이언트에세 메시지 전송 this. bw. flush(); } public String to. String(){ return socket. to. String(); } } } 3/19/2018

16. 6. 7 TCP Chat Client public class Chat. Client extends Frame implements Runnable, 16. 6. 7 TCP Chat Client public class Chat. Client extends Frame implements Runnable, Action. Listener{ private String nickname = null; //닉네임 private String serv. Addr = null; //서버 주소 private int serv. Port = 0; //서버 포트 private boolean flag = false; private Socket socket = null; //클라이언트 소켓 private Buffered. Reader br = null; //입력 스트림 private Buffered. Writer bw = null; //출력 스트림 private Text. Field tf 1 = new Text. Field(); private Text. Area ta 1 = new Text. Area(); public Chat. Client(String nickname, String serv. Addr, int serv. Port) throws IOException{ this. nickname = nickname; this. serv. Addr = serv. Addr; this. serv. Port = serv. Port; this. init. Graphics(); //그래픽작업과 이벤트 등록 초기화 this. init. Network(); //소켓 생성과 스트림 작업 초기화와 스레드 시작 new Thread(this). start(); } public void init. Graphics(){ 그래픽 컴포넌트 초기화 // } public void init. Network() throws IOException{ // } 소켓과 입출력 스트림 초기화 public void action. Performed(Action. Event e){ // 텍스트필드에 엔터가 클릭되었을 때의 이벤트 처리 } public void run(){ // } 데이터 받고 화면에 보여주기 public void stop(){ this. send. Message("[" + nickname + "]: 님이 퇴장합니다. "); this. flag = true; } public void send. Message(String msg){ try{ this. bw. write(msg + "n"); this. bw. flush(); }catch(IOException e){e. print. Stack. Trace(); } } } 3/19/2018 public void init. Graphics(){ this. tf 1. set. Background(Color. orange); this. ta 1. set. Background(Color. yellow); this. add("North", tf 1); this. add("Center", ta 1); this. tf 1. add. Action. Listener(this); this. add. Window. Listener(new Window. Adapter(){ public void window. Closing(Window. Event e){System. exit(0); stop(); }}); } public void init. Network() throws IOException{ this. socket = new Socket(serv. Addr, serv. Port); bw = new Buffered. Writer(new Output. Stream. Writer(socket. get. Output. Stream())); br = new Buffered. Reader(new Input. Stream. Reader(socket. get. Input. Stream())); this. send. Message("[" + nickname + "]: 님이 입장했습니다. "); } public void action. Performed(Action. Event e){ String msg = tf 1. get. Text(); if(!msg. equals("")){ this. send. Message("[" + nickname + "]: " + msg); tf 1. set. Text(""); } } public void run(){ try{ while(!flag){ String msg = br. read. Line(); if(msg != null && !msg. equals("")){ this. ta 1. append( msg +"n"); }else{ flag = true; } } br. close(); bw. close(); socket. close(); }catch(IOException e){e. print. Stack. Trace(); } }

16. 6. 8 채팅의 실행 3/19/2018 16. 6. 8 채팅의 실행 3/19/2018

17 ██████ 17 3/19/2018 17 ██████ 17 3/19/2018

17장 자바 RMI 소설같은 3 자바 rd Edition since 2001 최영관 Powered by http: 17장 자바 RMI 소설같은 3 자바 rd Edition since 2001 최영관 Powered by http: //www. jabook. org 3/19/2018

17. 1 RMI의 배경 3/19/2018 17. 1 RMI의 배경 3/19/2018

17. 1. 1 RMI의 기본 ▣ 네트워크 프로그램을 개발할 때의 중요한 두 가지 요소 17. 1. 1 RMI의 기본 ▣ 네트워크 프로그램을 개발할 때의 중요한 두 가지 요소 네트워크 프로그램의 안전성과 신뢰성 ◈ 프로그램 로직상의 안전성과 신뢰성 ◈ ▣ RMI(Remote Method Invocation) 아키텍처 RMI는 내부에서 네트워크의 통신 방법을 제공하기 때문에 통신상 의 신뢰성이 보장된다. ◈ 프로그래머는 프로그램의 로직(Logic)과 데이터의 흐름(Workflow) 만을 생각하면 된다. ◈ ▣ 미들웨어(Middleware)로서의 RMI ◈ RMI는 Socket 통신 자체를 하부에 숨기고, 상위 레벨의 프로그램만 을 할 수 있도록 제공되는 하나의 미들웨어(Middleware)이다. 3/19/2018

17. 1. 2 RPC & RMI ▣ 원격(Remote)이라는 용어 ◈ ▣ 원격 메서드 호출(Remote 17. 1. 2 RPC & RMI ▣ 원격(Remote)이라는 용어 ◈ ▣ 원격 메서드 호출(Remote Method Invocation) ◈ ▣ 네트워크의 안정성과 신뢰성은 RMI 아키텍처가 해결해주며, 원격지에 존재하는 메서드를 로컬머신에서 호출해 서 사용하기만 하면 된다. RPC와 RMI ◈ ◈ ▣ 로컬 머신에서 원격지의 메서드를 호출하면, 원격 컴퓨터의 CPU를 사용해서 메서드가 호출된다. 원격지 메서드 호출에 대한 요약 ◈ ▣ 누가 메서드를 호출하는가? 메서드가 호출되었을 때 누구의 CPU를 사용하는가? 메서드가 호출된 후 결과값은 누가 가지는가? 원격 메서드 호출과 CPU 사용 ◈ ▣ 원격 메서드 호출(RMI)이란 로컬(자신의) 컴퓨터에서 원격(멀리에 떨어져 있는) 컴퓨터의 메서드를 호출하는 기 술이다. RPC와 RMI의 핵심 ◈ ◈ ◈ ▣ 원격(Remote)은 멀리 떨어져 있다는 의미이다. RPC는 객체지향 기술이 포함되지 않은 단순한 메서드의 호출 RMI는 자바의 객체지향 기술이 가미된 원격 메서드 호출 RMI란? ◈ 자바 RMI는 원격지에 존재하는 객체의 멤버 메서드를 호출하는 기술이다. 3/19/2018

17. 1. 3 RPC 모델 ▣ RPC의 종류 ◈ ◈ ◈ ▣ J 2 17. 1. 3 RPC 모델 ▣ RPC의 종류 ◈ ◈ ◈ ▣ J 2 EE ◈ ◈ ▣ 웹로직(Web Logic)은 J 2 EE의 상업적인 모델 중 가장 널리 알려져 있는 모델이다. 웹로직 사이트 : http: //www. bea. com 응용 RMI 기술 ◈ ▣ J 2 EE는 비즈니스 로직을 처리하기 위한 RMI 기반의 응용모델 J 2 EE에서 서비스하는 객체를 EJB라고 한다. 웹로직(Web Logic) ◈ ◈ ▣ RMI는 자바 전용 RPC DCOM은 MS 전용 RPC CORBA는 모든 언어에 적용되는 RPC RMI를 이용해서 무엇을 할 것이냐에 따라서 응용 RMI 기술이 등장한다. RMI의 응용모델 ◈ ◈ 분산 처리 모델 분산 객체 모델 3/19/2018

17. 2 RMI의 동작원리 3/19/2018 17. 2 RMI의 동작원리 3/19/2018

17. 2. 1 클라이언트/서버 통신 메커니즘 원격 메서드의 논리적 호출 Client Remote Computer Client 17. 2. 1 클라이언트/서버 통신 메커니즘 원격 메서드의 논리적 호출 Client Remote Computer Client Program RMI Registry 메서드 호출 결과값 반환 원격 객체 (진짜객체) 원격 참조 객체 (가짜객체) RMI Communication RMI Server Program Client Remote Hello. Impl h = new Hello. Impl(); Naming. bind("rmi: //localhost/BABO", h); binding 원격 참조 객체 (가짜 객체) 1 Naming lookup BABO 2 원격 참조 객체 반환 3 4 3/19/2018 메서드 호출 결과값 반환 RMI Registry RMI Client Program BABO h 원격 객체 (진짜 객체)

17. 2. 2 원격 인터페이스, 클래스, 객체 ▣ 원격 인터페이스 ◈ ◈ ◈ ▣ 17. 2. 2 원격 인터페이스, 클래스, 객체 ▣ 원격 인터페이스 ◈ ◈ ◈ ▣ 원격 인터페이스를 만드는 규칙 1. Remote 인터페이스를 상속해야 한다. (인터페이스끼리의 상속) 2. 원격 인터페이스 내에 존재하는 모든 메서드에 throws Remote. Exception을 붙여야 한다. 원격 클래스의 구조 ◈ ◈ ◈ ▣ public interface IHello extends Remote{ public String say. Hello(String name) throws Remote. Exception; } public class Hello. Impl extends Unicast. Remote. Object implements IHello { //…클래스의 내용 } 원격 클래스로 해야 하는 일 원격 클래스 내부구조 ◈ ◈ public class Hello. Impl extends Unicast. Remote. Object implements IHello { public Hello. Impl() throws Remote. Exception { } public String say. Hello(String name) throws Remote. Exception{ } } 1. 원격 클래스를 이용해서 스텁(Stub) 클래스 작성 2. 원격 클래스를 이용해서 원격 객체를 생성한 후 바인딩 시키 는 프로그램 작성 스텁(Stub) ▣ 원격 클래스의 실제 구현 ◈ ◈ ◈ ◈ 1. 원격 클래스를 이용해서 스텁 클래스를 만든다. public class Hello. Impl extends Unicast. Remote. Object implements IHello { public Hello. Impl() throws Remote. Exception { } public String say. Hello(String name) throws Remote. Exception{ System. out. println(name + "님 안녕하십니까! "); return name + "님 안녕하십니까! "; } 스텁(Stub)을 만드는 방법 } 2. 스텁 클래스는 rmic. exe라는 툴을 이용해서 만든다. 3. 스텁 클래스의 객체는 원격 참조 객체가 된다. 1. javac Hello. Impl. java 원격 클래스를 만드는 규칙 2. rmic Hello. Impl 1. 원격 인터페이스를 구현해야 한다. rmic. exe로 생성된 스텁(Stub)과 스켈레톤(Skeleton) 파일 3/19/2018 1. Hello. Impl_Stub. class 2. Hello. Impl_Skeleton. class 2. Unicast. Remote. Object 클래스를 상속해야 한다.

17. 2. 3 Binding - 서버 프로그램 ▣ 지금까지 한 작업 정리 ◈ ◈ 17. 2. 3 Binding - 서버 프로그램 ▣ 지금까지 한 작업 정리 ◈ ◈ ◈ ▣ 바인딩을 위한 서버 프로그램의 구현 ◈ ◈ ◈ ◈ ▣ 원격 인터페이스의 작성 원격 클래스의 작성 스텁 작성 public class Hello. RMIServer{ public static void main(String[] args) throws Exception { //. . 중간생략 Hello. Impl h = new Hello. Impl(); Naming. rebind("rmi: //localhost: 1099/BABO", h); System. out. println("Hello. Impl형의 객체 h를 BABO라는 이름으로 바인딩 완료"); } } rmiregistry 시작하기 ◈ start rmiregistry 2000 – – ▣ 1099번 디폴트 포트 이용 2000번 포트로 rmiregistry 시작하기 전체 프로그램 실행 절차 ◈ ◈ ◈ IHello 원격 인터페이스 작성 Hello. Impl 원격 클래스 작성 Hello. Impl_Stub 작성 RMI Binding 프로그램 작성 RMI Registry 실행 RMI Binding 프로그램 실행 3/19/2018

17. 2. 4 Binding - 절차 Binding 과정 IHello 인터페이스 Hello. Impl 클래스 구현 17. 2. 4 Binding - 절차 Binding 과정 IHello 인터페이스 Hello. Impl 클래스 구현 원격 인터페이스 작성 RMI Server Program 서버 프로그램 작성 원격 클래스 작성 IHello h = new Hello. Impl(); Naming. bind("rmi: //localhost/BABO", h); 특정 위치에 스텁파일 위치시킴 클라이언트가 원격 객체를 룩업(Lookup)할 때 RMI Registry는 해당 원격 객체의 원격 참조 객체(가짜 객체)를 만들고 직렬화시켜서 전송한다. 3/19/2018 RMI Registry 스텁(Stub) 파일 작성 (file, ftp, http) rimc. exe를 이용 BABO 식별자 h 원격 객체 가짜객체를 위한 클래스 Hello. Impl_Stub. class Stub class 파일 Stub URL Location 서버 또는 클라이언트 프로그램을 실행할 때 Stub 파일의 위치를 codebase로 명시 바인딩

17. 2. 5 Lookup 룩업(Lookup) 과정 Remote Client RMI Server Program IHello h = 17. 2. 5 Lookup 룩업(Lookup) 과정 Remote Client RMI Server Program IHello h = new Hello. Impl(); Naming. bind("rmi: //localhost/BABO", h); Object obj = Naming. lookup( “rmi: //localhost/BABO“ ); 직렬화된 Stub 객체 2 직렬화된 Stub 객체 반환 Stub 객체 6 3 역직렬화를 위해 역직렬화 RMI Registry Naming lookup BABO h 원격 객체 Stub 파일 검색 obj codebase로 Stub class 파일의 위치 지정 4 스텁 class file 7 인터페이스를 이용해서 캐스팅 IHello ih = (IHello)obj; 8 Stub class 파일 요청 5 Stub class 파일 반환 ih를 이용해서 메서드 호출 (file, ftp, http) RMI Client Program 1 바인딩(Binding) 원격 객체의 Stub class Stub URL Location 참고 • 클라이언트 프로그램은 스텁(Stub) 클래스 파일의 위치를 codebase로 지정한 후 사용한다. • 스텁 파일은 서버와 클라이언트 모두 필요하다. 스텁 파일을 얻기 위해서 codebase에 지정된 URL을 검색한다. 3/19/2018 • 직렬화된 객체를 역직렬화하기 위해서는 해당 객체의 클래스 파일이 필요하다.

17. 2. 6 Stub과 Skeleton Client Remote Computer Client Program 8 Method Return RMI 17. 2. 6 Stub과 Skeleton Client Remote Computer Client Program 8 Method Return RMI Registry 1 메서드 호출 2 Stub marshaling 7 un - marshaling 5 4 Method Call 3 un - marshaling 메서드 반환값 Skeleton 6 marshaling 클라이언트와 서버 대리자 Remote Client 5 메서드 호출 대행 1 메서드 호출 대행 (매개변수첨부) 10 반환값 리턴 대행 6 반환값 리턴 대행 2 매개변수 마샬링 메서드 호출 대행 Stub 9 반환값 언마샬링 반환값 리턴 3 Skeleton에게 메서드 호출 요청 8 Stub에게 반환값 전달 4 7 매개변수 언마샬링 메서드 호출 대행 반환값 마샬링 반환값 리턴 Skeleton 서버 대리자 클라이언트 대리자 3/19/2018 RMI Registry Client Program

17. 2. 7 RMI Layer Remote Method Invocation Layer Client Remote Computer Client Program 17. 2. 7 RMI Layer Remote Method Invocation Layer Client Remote Computer Client Program 메서드 호출 Stub 4 2 Call 1 Return Client RMI 계층 RMI Registry Remote Reference Layer Transfer Layer 메서드 반환 Server RMI 계층 Skeleton Remote Reference Layer 실제 메서드 호출 물리적 계층 Transfer Layer 물리적 계층 TCP/IP 3/19/2018 3 Internet TCP/IP

17. 3 Hello Java RMI(자바 1. 2기준) 3/19/2018 17. 3 Hello Java RMI(자바 1. 2기준) 3/19/2018

17. 3. 1 1단계 원격 인터페이스 작성 ▣ 원격 인터페이스를 만들 때의 규칙 ◈ 17. 3. 1 1단계 원격 인터페이스 작성 ▣ 원격 인터페이스를 만들 때의 규칙 ◈ ◈ ▣ Remote 인터페이스의 원형 ◈ ◈ ◈ ▣ 원격 인터페이스는 반드시 java. rmi. Remote 인터페이스를 상속받아야 한다 모든 메서드는 java. rmi. Remote. Exception 타입의 예외를 처리해주어야 한다. public interface Remote { //내용없음 } 원격 인터페이스는 반드시 Remote 인터페이스를 상속받아야 한다. 원격 인터페이스의 모든 추상 메서드에 throws Remote. Exception을 붙여준다. IHello 원격 인터페이스 ◈ ◈ import java. rmi. *; public interface IHello extends Remote{ public String say. Hello(String name) throws Remote. Exception; } 3/19/2018

17. 3. 2 2단계 원격 클래스 구현 ▣ 2단계 ◈ ▣ 원격 클래스를 작성할 17. 3. 2 2단계 원격 클래스 구현 ▣ 2단계 ◈ ▣ 원격 클래스를 작성할 때의 규칙 ◈ ◈ ◈ ▣ 원격 인터페이스 구현해서 원격 클래스를 작성한다. 원격 인터페이스의 모든 메서드들을 구현해야 한다. java. rmi. server. Unicast. Remote. Object 클래스를 반드시 상속해야 한다. 원격 클래스의 생성자에 Remote. Exception 처리를 해야 한다. Hello. Impl 원격 클래스 ◈ ◈ ◈ ◈ ◈ 원격 클래스 public class Hello. Impl extends Unicast. Remote. Object implements IHello { public Hello. Impl() throws Remote. Exception{ } public String say. Hello(String name) throws Remote. Exception{ String str = name + "님 안녕하십니까! "; System. out. println(str); return str; } } 3/19/2018

17. 3. 3 3단계 Stub과 Skeleton 생성 ▣ 스텁 파일이 필요한 이유 스텁 파일은 17. 3. 3 3단계 Stub과 Skeleton 생성 ▣ 스텁 파일이 필요한 이유 스텁 파일은 원격 참조 객체의 메모리를 생성하기 위해서 서버측에서 필요 하다. ◈ 클라이언트에서 직렬화된 원격 참조 객체를 역직렬화하기 위해서 스텁 파 일이 필요하다. ◈ ▣ 스텁 파일을 만들기 위해서 필요한 요소 ◈ ◈ ▣ 원격 클래스 파일 rmic. exe 컴파일러 스텁과 스켈레톤을 만드는 예 ◈ ◈ ◈ c: javasrcchap 17Hello. RMIServer> rmic Hello. Impl c: javasrcchap 17Hello. RMIServer>dir Hello. Impl*. class 06 -26 오후 05: 31 725 Hello. Impl. class 03 -13 오후 05: 41 1, 798 Hello. Impl_Stub. class 2개 파일 2, 523 바이트 3/19/2018

17. 3. 4 4단계 서버 프로그램 작성 ▣ Hello RMI 서버 프로그램 ◈ ◈ 17. 3. 4 4단계 서버 프로그램 작성 ▣ Hello RMI 서버 프로그램 ◈ ◈ ◈ ▣ import java. rmi. *; import java. rmi. server. *; public class Hello. RMIServer{ public static void main(String[] args) throws Exception { if (System. get. Security. Manager() == null) { System. set. Security. Manager(new RMISecurity. Manager()); } Hello. Impl h = new Hello. Impl(); Naming. rebind("rmi: //localhost: 1099/BABO", h); System. out. println("Hello. Impl의 객체 h를 BABO이름으로 바인딩"); } } 정책파일(rmi. policy) ◈ grant { ◈ permission java. security. All. Permission; ◈ }; ▣ 실행 ◈ c: javasrcchap 17Hello. RMIServer>start rmiregistry 1099 ◈ c: javasrcchap 17Hello. RMIServer>javac Hello. RMIServer. java ◈ c: javasrcchap 17Hello. RMIServer>java -Djava. security. policy=rmi. policy Hello. RMIServer 3/19/2018

17. 3. 5 5단계 클라이언트 프로그램 작성 ▣ Hello RMI 클라이언트 프로그램 ◈ ◈ 17. 3. 5 5단계 클라이언트 프로그램 작성 ▣ Hello RMI 클라이언트 프로그램 ◈ ◈ ◈ ▣ 정책파일(rmi. policy) ◈ ◈ ◈ ▣ import java. rmi. *; public class Hello. RMIClient { public static void main(String[] args) throws Exception { if (System. get. Security. Manager() == null) { System. set. Security. Manager(new RMISecurity. Manager()); } IHello h = (IHello)Naming. lookup("rmi: //localhost: 1099/BABO"); String str = h. say. Hello("홍길동"); System. out. println(str); } } grant { permission java. security. All. Permission; }; 실행 ◈ ◈ ◈ //1. 원격 인터페이스로 사용할 클래스 파일 확보(IHello. class) //2. 원격 클라이언트 프로그램 컴파일 c: javasrcchap 17Hello. RMIClient>javac Hello. RMIClient. java //3. 원격 클라이언트 프로그램 실행 c: javasrcchap 17Hello. RMIClient>java -Djava. security. policy=rmi. policy Djava. rmi. server. codebase=http: //www. jabook. org/java 3/rmi/ Hello. RMIClient 3/19/2018

17. 3. 6 프로그램 데모 3/19/2018 17. 3. 6 프로그램 데모 3/19/2018

17. 3. 7 자바 1. 5 변경사항 ▣ 자바 1. 5의 변경 사항 rmic를 17. 3. 7 자바 1. 5 변경사항 ▣ 자바 1. 5의 변경 사항 rmic를 할 필요가 없다. ◈ 스텁은 내부에서 자동으로 생성되고 처리된다. ◈ ▣ 실제 작업 앞의 5단계 과정 중 3단계 자체가 필요없다. ◈ 서버에서 스텁을 공개적으로 서비스하지 않아도 된다. ◈ 클라이언트에서 codebase 없이 호출할 수 있다. ◈ ▣ 주의 ◈ 스텁과 스켈레톤을 사용하지 않는 것이 아니라 내부에서 자동으로 만들어지고 서비스된다. 3/19/2018

17. 4 Day. Time Java RMI 3/19/2018 17. 4 Day. Time Java RMI 3/19/2018

17. 4. 1 Day Time RMI Server ▣ Day. Time RMI를 위한 원격 인터페이스 17. 4. 1 Day Time RMI Server ▣ Day. Time RMI를 위한 원격 인터페이스 ◈ ◈ ◈ ▣ import java. rmi. *; import java. util. Date; public interface IDay. Time extends Remote{ public Date get. Day. Time() throws Remote. Exception; } Day. Time RMI를 위한 원격 클래스 ◈ ◈ ◈ ◈ ◈ import java. rmi. *; import java. rmi. server. *; import java. util. Date; public class Day. Time. Impl extends Unicast. Remote. Object implements IDay. Time{ public Day. Time. Impl() throws Remote. Exception{ //디폴트 생성자 } public Date get. Day. Time() throws Remote. Exception { return new Date(); } public static void main(String[] args) throws Exception { if (System. get. Security. Manager() == null) { System. set. Security. Manager(new RMISecurity. Manager()); } Day. Time. Impl d = new Day. Time. Impl(); //원격 객체의 생성 Naming. rebind("rmi: //localhost: 1099/DAYBABO", d); //바인딩 System. out. println("Day. Time. Impl was rebinded with name 'DAYBABO'"); } } 3/19/2018

17. 4. 2 Day Time RMI Client ▣ ▣ ▣ ▣ import java. rmi. 17. 4. 2 Day Time RMI Client ▣ ▣ ▣ ▣ import java. rmi. *; import java. util. Date; public class Day. Time. Client { public static void main(String[] args) throws Exception { if (System. get. Security. Manager() == null) { System. set. Security. Manager(new RMISecurity. Manager()); } String url = "rmi: //localhost: 1099/DAYBABO"; IDay. Time rdt = (IDay. Time)Naming. lookup(url); Date date = rdt. get. Day. Time(); System. out. println( "Today Time : "+ date); } } 3/19/2018

17. 5 Polling 기법을 이용한 RMI 채팅 3/19/2018 17. 5 Polling 기법을 이용한 RMI 채팅 3/19/2018

17. 5. 1 개요 ▣ RMI를 이용한 채팅 ◈ ▣ 원격 메서드를 이용한 채팅 17. 5. 1 개요 ▣ RMI를 이용한 채팅 ◈ ▣ 원격 메서드를 이용한 채팅 구현 폴링(Polling) 기법 클라이언트에서 서버의 메서드를 호출하는 방식 ◈ 지금까지 테스트한 Hello. RMI와 Day. Time. RMI에서 사용한 기법을 말 한다. ◈ ▣ 콜백(Callback) 기법 ◈ 폴링과 반대되는 개념으로 클라이언트의 원격 메서드를 서버에서 호출하는 방식 3/19/2018

17. 5. 2 Polling 기법 Chat 서버-원격인터페이스 ▣ Polling 채팅을 위한 원격 인터페이스 ◈ 17. 5. 2 Polling 기법 Chat 서버-원격인터페이스 ▣ Polling 채팅을 위한 원격 인터페이스 ◈ ◈ ◈ ▣ String[] add. Message(String id, String message) ◈ ▣ import java. rmi. *; public interface IPolling. Chat extends Remote { public abstract String[] get. Message(int index) throws Remote. Exception; public abstract void add. Message(String id, String message) throws Remote. Exception; } 원격 클라이언트가 원격 서버로 메시지를 저장하기 위해서 사용한다. void get. Message(int index) ◈ 원격 클라이언트가 서버에 존재하는 메시지를 리턴받는다. 3/19/2018

17. 5. 3 Polling 기법 Chat 서버-원격 클래스 ▣ ▣ ▣ public class Polling. 17. 5. 3 Polling 기법 Chat 서버-원격 클래스 ▣ ▣ ▣ public class Polling. Chat. Impl extends Unicast. Remote. Object implements IPolling. Chat{ protected Vector v = new Vector(); public Polling. Chat. Impl() throws Remote. Exception { //내용없음 } ▣ ▣ ▣ ▣ public String[] get. Message(int index) { int size = v. size(); String[] messages=new String[size-index]; for(int i=0; i

17. 5. 4 Polling 기법 Chat 서버-실행 ▣ 스텁과 스켈레톤의 생성 ◈ ◈ ◈ 17. 5. 4 Polling 기법 Chat 서버-실행 ▣ 스텁과 스켈레톤의 생성 ◈ ◈ ◈ ▣ rmiregistry의 실행 ◈ ▣ c: javasrcchap 17PollingServer>start rmiregistry Polling. Chat. Impl의 스텁 파일이 공개되는 위치 ◈ ◈ ▣ c: javasrcchap 17PollingServer>rmic Polling. Chat. Impl c: javasrcchap 17PollingServer>dir Polling. Chat. Impl*. class 오전 11: 20 1, 646 Polling. Chat. Impl. class 오전 11: 20 2, 140 Polling. Chat. Impl_Stub. class 2개 파일 3, 786 바이트 http: //www. jabook. org/java 3/rmi/Polling. Chat. Impl_Stub. class 현재 지정된 위치가 아니더라도 여러분이 원하는 HTTP 서버에 위치시켜도 된다. 지금까지의 준비 사항 ◈ ◈ 원격 클래스와 서버 프로그램 구현 스텁과 스켈레톤 생성 정책 파일 생성 스텁 파일의 공개 3/19/2018

17. 5. 5 Polling 기법 Chat 클라이언트 public class Polling. Chat. Client extends Thread 17. 5. 5 Polling 기법 Chat 클라이언트 public class Polling. Chat. Client extends Thread { protected static final int WAIT_TIME = 1000; protected String id; protected IPolling. Chat server; public Polling. Chat. Client(String id) throws Not. Bound. Exception, Malformed. URLException, Remote. Exception{ this. id = id; System. out. println(id+"님 채팅 시작"); String url = "rmi: //localhost: 1099/CHATBABO"; this. server = (IPolling. Chat)Naming. lookup(url); this. start(); } public synchronized void play() throws Exception { // 메시지 입력받아 보내기 } public void run() { // 메시지 받고 출력하기 } public static void main(String[] args) throws Exception { if (System. get. Security. Manager() == null) { System. set. Security. Manager(new RMISecurity. Manager()); } Polling. Chat. Client c = new Polling. Chat. Client(args[0]); c. play(); } } 3/19/2018 public synchronized void play() throws Exception { String temp; Buffered. Reader br; br = new Buffered. Reader(new Input. Stream. Reader(System. in)); while((temp=br. read. Line()) != null){ if(temp. equals("exit")){ server. add. Message(id, id+"님 퇴장 "); System. exit(0); }else{ server. add. Message(id, temp); } } } public void run() { int index = 0; try{ while(! Thread. interrupted()) { String[] messages = server. get. Message(index); int n = messages. length; for(int i=0; i

3/19/2018 3/19/2018

17. 6 Call. Back 기법을 이용한 RMI 채팅 3/19/2018 17. 6 Call. Back 기법을 이용한 RMI 채팅 3/19/2018

17. 6. 1 RMI Call. Back 기법 ▣ 폴링(Polling) 기법 ◈ ▣ 콜백(Callback)기법 ◈ 17. 6. 1 RMI Call. Back 기법 ▣ 폴링(Polling) 기법 ◈ ▣ 콜백(Callback)기법 ◈ ▣ 클라이언트에 원격 객체가 위치하고 있으며, 서버에서 클라이언트 에 위치한 원격 객체를 호출하는 기법 풀링(Polling) 기법의 특징 ◈ ▣ 원격 서버에 위치한 원격 객체의 메서드를 클라이언트에서 호출하 는 일반적인 RMI 기법 클라이언트가 원할 때에만 서버의 메서드를 실행하는 것이 아니라 콜백(Callback)기법의 특징 ◈ 서버가 원할 때에 클라이언트의 메서드를 호출하는 것이 가능하다. 3/19/2018

17. 6. 2 Polling과 Call. Back의 원격 인터페이스 ▣ 콜백(Call. Back) 채팅을 위한 서버측 17. 6. 2 Polling과 Call. Back의 원격 인터페이스 ▣ 콜백(Call. Back) 채팅을 위한 서버측 원격 인터페이스 ◈ ◈ ◈ ▣ import java. rmi. *; public interface IChat. Server extends Remote { public void add. Client(Chat. Client client, String name) throws Remote. Exception; public void disconnect(Chat. Client client, String name) throws Remote. Exception; public void say(String msg) throws Remote. Exception; } 콜백(Callback) 채팅을 위한 클라이언트측 원격 인터페이스 import java. rmi. *; ◈ public interface Chat. Client extends Remote { ◈ public void print. Message(String msg) throws Remote. Exception; ◈ } ◈ 3/19/2018

17. 6. 3 서버측 원격 클래스의 구현 ▣ ▣ ▣ public class Chat. Server. 17. 6. 3 서버측 원격 클래스의 구현 ▣ ▣ ▣ public class Chat. Server. Impl extends Unicast. Remote. Object implements IChat. Server { private Vector buffer = new Vector(); public Chat. Server. Impl() throws Remote. Exception{} ▣ ▣ ▣ public void add. Client(Chat. Client client, String name) throws Remote. Exception{ buffer. add. Element(client); say(name + "님이 접속하셨습니다. "); System. out. println("New Client! Num of client=" + (buffer. size())); } ▣ ▣ ▣ ▣ ▣ public void disconnect(Chat. Client client, String name) throws Remote. Exception{ int i = buffer. index. Of(client); if (i >= 0){ say(name + "님이 퇴장하셨습니다. "); buffer. remove. Element. At(i); System. out. println("Client Exited! Num of client=" + buffer. size()); }else { System. out. println("No such a client in Server! "); } } ▣ ▣ ▣ public void say(String msg) throws Remote. Exception { for(int i = 0; i < buffer. size(); i++){ ((Chat. Client)buffer. element. At(i)). print. Message(msg); } } ▣ ▣ ▣ ▣ ▣ public static void main(String args[]) throws Exception{ if (System. get. Security. Manager() == null) { System. set. Security. Manager(new RMISecurity. Manager()); } Chat. Server. Impl csi = new Chat. Server. Impl(); System. out. println("RMI Callback Chat Server is running…"); Naming. rebind("rmi: //localhost: 1099/CALLBABO", csi); } 3/19/2018 }

17. 6. 4 클라이언트측 원격 클래스의 구현 ▣ 콜백(Callback) 채팅을 위한 클라이언트측 원격 인터페이스 17. 6. 4 클라이언트측 원격 클래스의 구현 ▣ 콜백(Callback) 채팅을 위한 클라이언트측 원격 인터페이스 ◈ ◈ ◈ ▣ public interface Chat. Client extends Remote { public void print. Message(String msg) throws Remote. Exception; } 콜백 기법으로 구현된 채팅 클라이언트 프로그램 ◈ ◈ ◈ ◈ ◈ ◈ public class Chat. Client. Impl extends Unicast. Remote. Object implements Chat. Client, Runnable { private IChat. Server server = null; protected static String name = null; public Chat. Client. Impl(String name) throws Remote. Exception, Exception { this. name = name; String url = "rmi: //localhost: 1099/CALLBABO"; server = (IChat. Server)Naming. lookup(url); server. add. Client(this, name); } public void print. Message(String msg) throws Remote. Exception { System. out. println(msg); public void run(){ } try { public void run(){ Buffered. Reader br; 메시지 입력받고 전송하기 br = new Buffered. Reader(new Input. Stream. Reader(System. in)); } public static void main(String[] args) throws Exception { if (System. get. Security. Manager() == null) { String message = null; while ((message = br. read. Line())!= null) { this. server. say(""+ name +" : " + message); System. set. Security. Manager(new RMISecurity. Manager()); if(message. equals("exit")){ } new Thread(new Chat. Client. Impl(args[0])). start(); server. disconnect(this, name); } } }catch(Exception e) { System. out. println(e); 3/19/2018 } }

17. 6. 5 Callback 기법을 이용한 채팅 데모 3/19/2018 17. 6. 5 Callback 기법을 이용한 채팅 데모 3/19/2018

End ██████ End 3/19/2018 End ██████ End 3/19/2018