Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "(분산 통신 실습 1) : 소켓(Sockets)"— Presentation transcript:

1 (분산 통신 실습 1) : 소켓(Sockets)
소켓: 저수준 패킷 스트림 전송 유닉스 소켓 (cseunix.incheon.ac.kr 에서 프로그램) 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 버전을 작성하세요. Information의 Unix의 Socket Programming 참조

2 Sockets

3 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 /* 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;

4 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);

5 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));

6 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 */

7 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 */

8 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;

9 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;

10 Time-of-Day: Client.java
import java.net.*; import java.io.*; public class Client { public Client() { try { Socket s = new Socket(" ",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();

11 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를 사용, 키보드 입력은 메인에서 처리

12 (분산 통신 실습 2) RMI RMI 익히기 분산환경에서 동작하는 message-passing을 이용한 bounded-buffer 해법 프로그램을 실행해 보세요. 소스 코드: ftp:// > os -> OSJavaSources -> ch15 -> rmi 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( )의 /mysung/2003osreport 디렉토리에 자기 학번 디렉토리를 만들고 소스 프로그램과 실행 파일을 옮겨 놓으세요.

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

14 RMI (Remote Method Invocation)

15 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

16 Marshalling Parameters

17 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

18 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 "*: ","connect,accept"; };

19 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)

20 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; }

21 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());

22 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; }

23 RMI 프로그램 예제 서버 : MessageQueueImpl.java (3)
public static void main(String args[]) { System.setSecurityManager(new RMISecurityManager()); try { MessageQueue server = new MessageQueueImpl(); Naming.rebind("// /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;

24 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(“// /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);

25 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;

26 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;

27 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;


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

Similar presentations


Ads by Google