(분산 통신 실습 1) : 소켓(Sockets)

Slides:



Advertisements
Similar presentations
Chap15 네트워킹 Section 1 : 네트워킹의 개요와 java.net 패키지 Section 2 : 인터넷 주소와 URL
Advertisements

11장. 프로토콜 핸들러 AI &HC I LAB 김 성 현.
Java Socket 통신 이개혁 정대준.
어서와 Java는 처음이지! 제2장 자바 프로그래밍 기초.
10. 예외 처리.
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
Understanding of Socket and File I/O
13장 소켓.
Programming for the java Virtual machine
제14장 원격 메소드 호출 김 기 환. 조 명 휘.
명품 JAVA Programming 제 13 장 스레드와 멀티태스킹.
C 프로그래밍 소개 숙명여대 창병모 2011 가을.
제 4장 문 장 배정문 혼합문 제어문 표준 입출력.
TCP/IP 소켓 프로그래밍 - C 버전 중에서
제6장 제어(Control) 6.1 구조적 프로그래밍(Structured Programming)
Department of Computer Engineering
네트워크 프로그래밍 Unix Network Programming, 2nd Ed., W. Richard Stevens, Prentice Hall PTR, 한국어 판 Unix Network Programming, Stevens 저, 김치하, 이재용 역, 대영사,
2주 실습강의 Java의 기본문법(1) 인공지능연구실.
임베디드 프로그래밍 Lecture #
제7장 제어구조 I – 식과 문장.
[ 단원 08 ] 예외처리와 스레드.
메소드 호출과 힙 원격 메소드 호출 서블릿 엔터프라이즈 자바 빈즈
Java RMI (Remote Method Invocation)
Java RMI (Remote Method Invocation)
TCP Client/Server Program
Network Lab. Seoung Hyeon, Lee
JAVA 프로그래밍 6장 객체지향프로그래밍의 핵심.
호스트이름과 네트워크이름 찾기 (Hostname and Network Name Lookups)
Internet Address Conversion Functions
6장 비연결형 지향 프로토콜 Database Lab 강 우 석.
인터넷 주소 변환 School of Electronics and Information. Kyung Hee University.
14장 소켓.
제 12장 I/O멀티플렉싱(Multiplexing)
JAVA 프로그래밍 12장 네트워킹(Networking).
10장 SafeTalk 시스템 소프트웨어 연구실 성순화 이재일
명품 JAVA Programming 제 16 장 네트워크.
명품 Java Programming.
Department of Computer Engineering
제2부 프로세스 관리(Process Management)
최용술 장 Thread 최용술
10장 다중 스레드 10.1 스레드 개요 10.2 Thread 클래스 10.3 스레드 생성
2장 자바환경과 자바 프로그램 2.1 자바 개발 환경 2.2 자바 통합환경 2.3 자바 응용 프로그램과 애플릿 프로그램
Socket Address Structure and Byte Ordering Functions
Department of Computer Engineering
DataScience Lab. 박사과정 김희찬 (월)
Socket Address Structure and Byte Ordering Functions
Homework 6… 12월 2일(금) 11:59pm까지 자신의 이름과 학번을 출력해 주는 유닉스/리눅스 네트워크 소켓 서버 프로그램 과 클라이언트 프로그램 을 작성해 보세요 참고 (실습1) Hello 프로그램 helloserver.c helloclient.c 컴파일.
5장 스레드 (Threads) 스레드 (Threads) 개요 ~
Chapter 8 연결형 프로토콜 서버 발표자 : SE Lab 황 성 하
Department of Computer Engineering
Network Programming(1)
JDBC (Java Database Connectivity)
adopted from KNK C Programming : A Modern Approach
03. 안드로이드를 위한 Java 문법 제목. 03. 안드로이드를 위한 Java 문법 제목.
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
(분산 통신 실습) : 소켓(Sockets)
School of Electronics and Information. Kyung Hee University.
제 2장 어휘구조와 자료형 토 큰 리 터 럴 주 석 자 료 형 배 열 형.
네트워크 프로그래밍의 이해 School of Electronics and Information.
User Datagram Protocol (UDP)
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
컴퓨터공학실습(I) 3주 인공지능연구실.
Chapter 16 Socket Interface.
Department of Computer Engineering
Internet Computing KUT Youn-Hee Han
Java 3장. 자바의 기본 구조 I : 변수, 자료형, 연산자 public class SumTest {
Java RMI (Remote Method Invocation)
Chapter 03. 소켓 주소 구조체 다루기.
소켓의 생성과 프로토콜의 설정 School of Electronics and Information.
임베디드 프로그래밍 Lecture #
Presentation transcript:

(분산 통신 실습 1) : 소켓(Sockets) 소켓: 저수준 패킷 스트림 전송 유닉스 소켓 (cseunix.incheon.ac.kr 211.119.245.68 에서 프로그램) inettime 소스 코드 참조 (실습) 시간을 10회 반복하여 출력하도록 프로그램을 수정하세요. (과제 1-1) 유닉스 채팅 프로그램 채팅 서버가 임의의 클라이언트가 채팅에 참가하는 요청을 하면 이를 채팅 참가자 리스트에 추가하며 채팅에 참가하고 있는 클라이언트들이 보내 오는 메시지를 모든 채팅 참가자에게 다시 방송하는 기능을 수행해 주는 chat_server.c와 chat_client.c 인터넷 채팅 프로그램을 실행하고 분석해 보고, 이 채팅 프로그램에 채팅 참가자 목록을 보여주는 ?who 명령을 추가하세요. 자바 소켓 시간(Time-of-Day) 서버 소스 코드 참조 (실습a) 시간을 10회 반복하여 출력하도록 프로그램을 수정하세요. (실습b) 유닉스 inettime 클라이언트와 혼합해서 inettime 서비스를 실행해 보세요. (과제 1-2) 자바 응용 채팅 프로그램 JavaChatServer.java와 JavaChatClient.java 및 JavaChatClient.html 자바 애플릿 채팅 프로그램을 inettime과 같은 자바 응용 채팅 프로그램으로 수정하세요. 윈도우 소켓(winsock) (실습) 유닉스 소켓 chat 프로그램을 윈도우 소켓 chat 프로그램으로 변경하세요. (과제 1-3) 윈도우 소켓 talk 프로그램 유닉스 talk 프로그램의 winsock 버전을 작성하세요. http://marvel.incheon.ac.kr/의 Information의 Unix의 Socket Programming 참조

Sockets

inettime.c: 인터네트 시간청취 #include <stdio.h> #include <signal.h> #include <ctype.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> /* For AFINET sockets */ #include <arpa/inet.h> #include <netdb.h> #define DAYTIME_PORT 13 /* Standard port no */ #define DEFAULT_PROTOCOL 0 unsigned long promptForINETAddress (); unsigned long nameToAddr (); main () { int clientFd; /* Client socket file descriptor */ int serverLen; /* Length of server address structure */ int result; /* From connect () call */ struct sockaddr_in serverINETAddress; /* Server address */ struct sockaddr* serverSockAddrPtr; /* Pointer to address */ unsigned long inetAddress; /* 32-bit IP address */ /* Set the two server variables */ serverSockAddrPtr = (struct sockaddr*) &serverINETAddress;

inettime.c: 인터네트 시간청취(cont.) serverLen = sizeof (serverINETAddress); /* Length of address */ while (1) /* Loop until break */ { inetAddress = promptForINETAddress (); /* Get 32-bit IP */ if (inetAddress == 0) break; /* Done */ /* Start by zeroing out the entire address structure */ bzero ((char*)&serverINETAddress,sizeof(serverINETAddress)); serverINETAddress.sin_family = AF_INET; /* Use Internet */ serverINETAddress.sin_addr.s_addr = inetAddress; /* IP */ serverINETAddress.sin_port = htons (DAYTIME_PORT); /* Now create the client socket */ clientFd = socket (AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL); do /* Loop until a connection is made with the server */ result = connect (clientFd,serverSockAddrPtr,serverLen); if (result == -1) sleep (1); /* Try again in 1 second */ } while (result == -1); readTime (clientFd); /* Read the time from the server */ close (clientFd); /* Close the socket */ exit (/* EXIT_SUCCESS */ 0);

inettime.c: 인터네트 시간청취(cont.) unsigned long promptForINETAddress () { char hostName [100]; /* Name from user: numeric or symbolic */ unsigned long inetAddress; /* 32-bit IP format */ /* Loop until quit or a legal name is entered */ /* If quit, return 0 else return host's IP address */ do printf ("Host name (q = quit, s = self): "); scanf ("%s", hostName); /* Get name from keyboard */ if (strcmp (hostName, "q") == 0) return (0); /* Quit */ inetAddress = nameToAddr (hostName); /* Convert to IP */ if (inetAddress == 0) printf ("Host name not found\n"); } while (inetAddress == 0); unsigned long nameToAddr (name) char* name; char hostName [100]; struct hostent* hostStruct; /* /usr/include/netdb.h */ struct in_addr* hostNode; /* Convert name into a 32-bit IP address */ /* If name begins with a digit, assume it's a valid numeric */ /* Internet address of the form A.B.C.D and convert directly */ if (isdigit (name[0])) return (inet_addr (name));

inettime.c: 인터네트 시간청취(cont.) if (strcmp (name, "s") == 0) /* Get host name from database */ { gethostname (hostName,100); printf ("Self host name is %s\n", hostName); } else /* Assume name is a valid symbolic host name */ strcpy (hostName, name); /* Now obtain address information from database */ hostStruct = gethostbyname (hostName); if (hostStruct == NULL) return (0); /* Not Found */ /* Extract the IP Address from the hostent structure */ hostNode = (struct in_addr*) hostStruct->h_addr; /* Display a readable version for fun */ printf ("Internet Address = %s\n", inet_ntoa (*hostNode)); return (hostNode->s_addr); /* Return IP address */ readTime (fd) int fd; char str [200]; /* Line buffer */ printf ("The time on the target port is "); while (readLine (fd, str)) /* Read lines until end-of-input */ printf ("%s\n", str); /* Echo line from server to user */

inettime.c: 인터네트 시간청취(cont.) readLine (fd, str) int fd; char* str; /* Read a single NEWLINE-terminated line */ { int n; do /* Read characters until NULL or end-of-input */ n = read (fd, str, 1); /* Read one character */ } while (n > 0 && *str++ != '\n'); return (n > 0); /* Return false if end-of-input */

Time-of-Day: Server.java import java.net.*; public class Server { public Server() { // create the socket the server will listen to try { s = new ServerSocket(5155); } catch (java.io.IOException e) { System.out.println(e); System.exit(1); // OK, now listen for connections System.out.println("Server is listening ...."); while (true) { client = s.accept(); // create a separate thread // to service the request c = new Connection(client); c.start(); public static void main(String args[]) { Server timeOfDayServer = new Server(); private ServerSocket s; private Socket client; private Connection c;

Time-of-Day: Connection.java import java.net.*; import java.io.*; public class Connection extends Thread { public Connection(Socket s) { outputLine = s; } public void run() { // getOutputStream returns an OutputStream object // allowing ordinary file IO over the socket. try { // create a new PrintWriter with automatic flushing PrintWriter pout = new PrintWriter(outputLine.getOutputStream(), true); // now send a message to the client pout.println("The Date and Time is " + new java.util.Date().toString()); Thread.sleep(1500); catch (Exception e) { } // now close the socket outputLine.close(); catch (java.io.IOException e) { System.out.println(e); private Socket outputLine;

Time-of-Day: Client.java import java.net.*; import java.io.*; public class Client { public Client() { try { Socket s = new Socket("127.0.0.1",5155); InputStream in = s.getInputStream(); BufferedReader bin = new BufferedReader(new InputStreamReader(in)); System.out.println(bin.readLine()); s.close(); } catch (java.io.IOException e) { System.out.println(e); System.exit(1); public static void main(String args[]) { Client client = new Client();

talk & chat Winsock versions 윈도우 소켓(Window socket)은 유닉스에서 사용되는 BSD소켓을 계승하기 때문에 윈속에서 사용되는 대부분의 함수와 구조체는 유닉스 버전과 동일하다. 그러나 윈속을 사용하기 전에 유닉스와 달리 윈속 라이브러리를 초기화 해주고 사용이 끝나면 해제를 시켜줘야 한다. 초기화 : WSAStartup, 해제 : WSACleanup talk_client, talk_server 유닉스 버전 : 키보드 입력과 데이터 수신 처리를 fork를 이용해서 분기 윈도우 버전 : 키보드 입력은 메인에서, 데이터수신 처리는 쓰레드를 이용 chat_client, chat_server 유닉스 버전 : select를 사용하여 데이터 I/O를 비동기적으로 처리, 키보드 입력은 fork를 이용 윈도우 버전 : I/O방식은 쓰레드에서 select를 사용, 키보드 입력은 메인에서 처리

(분산 통신 실습 2) RMI RMI 익히기 분산환경에서 동작하는 message-passing을 이용한 bounded-buffer 해법 프로그램을 실행해 보세요. 소스 코드: ftp://211.119.245.153 -> os -> OSJavaSources -> ch15 -> rmi http://marvel el.incheon.ac.kr의 InformationUnix RMI 참조 또, 이 예제가 웹 상에서 수행될 수 있도록 수정해 보세요. 즉 클라이언트 프로그램에서 이 예제의 Producer와 Consumer의 동작을 모니터링하는 Java applet을 작성해 보는 것입니다. Appletviewer 또는 넷스케이프 커뮤니케이터로 실행 BONUS: Java synchronization을 이용한 bounded-buffer 해법(운영체제 교재 Applied Operating System Concepts 7장 p209 참조)이 분산 환경에서도 동작할 수 있도록 RMI를 이용하여 수정해 보세요. 실습방법 cseblade.incheon.ac.kr(211.119.245.68)의 /mysung/2003osreport 디렉토리에 자기 학번 디렉토리를 만들고 소스 프로그램과 실행 파일을 옮겨 놓으세요.

RMI (Remote Method Invocation) RPC의 Java 버전 저수준(low-level) 소켓을 이용하지 않고 원격 객체의 메소드를 호출할 수 있는 방법을 제공하는 객체 지향 언어인 Java 기반의 분산 컴퓨팅 환경(클라이언트/서버 지원)을 위한 미들웨어(RPC와 유사) 스레드(thread)가 원격 객체(Remote Object)의 메소드(method) 호출 다른 Java Virtual Machine 상에 있는 객체는 “원격” 객체 RPC 보다 좋은점 객체 지향적이다. 프로그램 작성 및 사용이 쉽다. 안전하고 보안성이 있다. 기존 시스템과 통합해서 사용할 수 있다. 작성 절차 원격 인터페이스를 정의한다. 원격 인터페이스를 구현(implement)하는 원격 객체(서버)를 작성한다. 원격 객체를 이용하는 프로그램(클라이언트)을 작성한다. stub와 skeleton 클래스를 생성한다. rmiregistry를 실행시킨다. 서버와 클라이언트를 실행시킨다.

RMI (Remote Method Invocation)

RMI (Remote Method Invocation) RPC versus RMI RPC : Procedural Programming Style RMI : Object-Oriented Programming Style RPC의 매개변수 : Ordinary Data Structures RMI의 매개변수 : Objects Stubs and Skeletons “Stub” 클라이언트에 상주하는 원격 객체의 대리인(proxy) 매개변수들을 “Marshalls”(메소드 이름과 인자들의 꾸러미 생성)해서 서버로 보냄 “Skeleton” 서버에 상주 매개변수를 “Unmarshalls” 해서 서버에 전달함 매개변수 Marshall된 매개변수가 Local (Non-Remote) Objects이면 객체를 바이트 스트림으로 기록해 주는 객체 순서화(Object Serialization) 기법을 이용해서 복사에 의해(by Value) 전달 Marshall 된 매개변수가 Remote Objects이면 참조에 의해(by Reference) 전달 : RMI의 장점 Remote objects java.rmi.Remote를 확장한 Interface로 선언되어야 함 … extends java.rmi.Remote 모든 메소드는 java.rmi.RemoteException을 발생시켜야 함 … throws java.rmi.RemoteException

Marshalling Parameters

RMI 프로그램 예제 javac rmic javac server client 원격 인터페이스 구현 MessageQueueImpl.java javac MessageQueueImpl.class MessageQueue.java MessageQueueImpl_skel.class rmic MessageQueueImpl_stub.class Factory.java Producer.java javac Factory.class Consumer.java client

RMI 프로그램 예제 Policy File : New with Java 2 grant { 구성 원격 인터페이스: MessageQueue.java 서버 프로그램: MessageQueueImpl.java 클라이언트 프로그램: Factory.java, Producer.java, Consumer.java Policy File : New with Java 2 grant { permission java.net.SocketPermission "*:1024-65535","connect,accept"; };

RMI 프로그램 예제 실행 순서 모든 소스 파일 컴파일 # javac MessageQueue.java MessageQueueImpl.java Factory.java Producer.java Consumer.java rmic로 stub와 skeleton class 파일 생성 # rmic MessageQueueImpl 레지스트리 서비스 시작 (rmiregistry) … osagent 또는 rpcbind 디몬에 해당 # rmiregistry & (Unix) 또는 C:\> start rmiregistry (Windows) 원격 서버 객체의 인스턴스 생성 (JDK 1.2 이상 버전에서는 인증해 주어야 함) # java -Djava.security.policy=java.policy MessageQueueImpl (JDK 1.2 이상) 또는 # java MessgeQueueImpl (JDK 1.1) 클라이언트에서 원격 객체 실행 시작 # java -Djava.security.policy=java.policy Factory (JDK .2 이상) 또는 # java Factory (JDK 1.1)

RMI 프로그램 예제 서버 : MessageQueue interface import java.util.*; import java.rmi.*; public interface MessageQueue extends java.rmi.Remote { /* * This implements a non-blocking send */ public void send(Object item) throws java.rmi.RemoteException; * This implements a non-blocking receive public Object receive() throws java.rmi.RemoteException; }

RMI 프로그램 예제 서버 : MessageQueueImpl.java (1) import java.util.*; import java.rmi.*; public class MessageQueueImpl extends java.rmi.server.UnicastRemoteObject implements MessageQueue { public MessageQueueImpl() throws RemoteException { queue = new Vector(); } // This implements a non-blocking send public synchronized void send(Object item) throws RemoteException { queue.addElement(item); System.out.println("Producer entered " + item + " size = " + queue.size());

RMI 프로그램 예제 서버 : MessageQueueImpl.java (2) // This implements a non-blocking receive public synchronized Object receive() throws RemoteException { Object item; if (queue.size() == 0) return null; else { item = queue.firstElement(); queue.removeElementAt(0); System.out.println("Consumer removed " + item + " size = " + queue.size()); return item; }

RMI 프로그램 예제 서버 : MessageQueueImpl.java (3) public static void main(String args[]) { System.setSecurityManager(new RMISecurityManager()); try { MessageQueue server = new MessageQueueImpl(); Naming.rebind("//127.0.0.1/MessageServer", server); //Naming.rebind("rmi://media.inchon.ac.kr/MessageServer", server); System.out.println("Server Bound"); } catch(Exception e) { System.err.println(e); private Vector queue;

RMI 프로그램 예제 클라이언트 : Factory.java (1) import java.util.*; import java.rmi.*; public class Factory { public Factory() { // remote object MessageQueue mailBox; System.setSecurityManager(new RMISecurityManager()); // install a security manager try { //get a reference to the remote object mailBox = (MessageQueue)Naming.lookup(“//127.0.0.1/MessageServer"); //(MessageQueue)Naming.lookup("rmi://media.inchon.ac.kr/MessageServer"); // now create the producer and consumer threads Producer producerThread = new Producer(mailBox); Consumer consumerThread = new Consumer(mailBox); producerThread.start(); consumerThread.start(); } catch (Exception e) { System.err.println(e);

RMI 프로그램 예제 클라이언트 : Factory.java (2) // producer and consumer will call this to nap public static void napping() { int sleepTime = (int) (NAP_TIME * Math.random() ); try { Thread.sleep(sleepTime*1000); } catch(InterruptedException e) { } } public static void main(String args[]) { Factory client = new Factory(); private static final int NAP_TIME = 5;

RMI 프로그램 예제 클라이언트 : Producer.java import java.util.*; class Producer extends Thread{ public Producer(MessageQueue m) { mbox = m; } public void run() { Date message; while (true) { Factory.napping(); // produce an item & enter it into the buffer message = new Date(); try { mbox.send(message); System.out.println(“Producer Produced ” + message); } catch (Exception e) { System.err.println(e); private MessageQueue mbox;

RMI 프로그램 예제 클라이언트 : Consumer.java import java.util.*; class Consumer extends Thread { public Consumer(MessageQueue m) { mbox = m; } public void run() { Date message; while (true) { Factory.napping(); // consume an item from the buffer try { message = (Date)mbox.receive(); if (message != null) // Consume the item System.out.println(“Consumer Consumed ” + message); catch (Exception e) { System.err.println(e); private MessageQueue mbox;