100 likes | 326 Views
실습 및 과제 1: 소켓( Sockets). 소켓 : 저수준 패킷 스트림 전송 유닉스 소켓 (211.119.245.149 에서 프로그램 ) inettime 소스 코드 참조 ( 실습 ) 시간을 10 회 반복하여 출력하도록 프로그램을 수정하세요 . ( 과제 1-1) 유닉스 채팅 프로그램
E N D
실습 및 과제 1: 소켓(Sockets) • 소켓: 저수준 패킷 스트림 전송 • 유닉스 소켓 (211.119.245.149에서 프로그램) • inettime 소스 코드 참조 • (실습) 시간을 10회 반복하여 출력하도록 프로그램을 수정하세요. • (과제 1-1) 유닉스 채팅 프로그램 채팅 서버가 임의의 클라이언트가 채팅에 참가하는 요청을 하면 이를 채팅 참가자 리스트에 추가하며 채팅에 참가하고 있는 클라이언트들이 보내 오는 메시지를 모든 채팅 참가자에게 다시 방송하는 기능을 수행해 주는 chat_server.c와 chat_client.c 인터넷 채팅 프로그램을 실행하고 분석해 보고, 이 채팅 프로그램에 채팅 참가자 목록을 보여주는 ?who 명령을 추가하세요. • 자바소켓 • 시간(Time-of-Day) 서버 소스 코드 참조 • (실습) 유닉스 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 참조
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 ...."); try { while (true) { client = s.accept(); // create a separate thread // to service the request c = new Connection(client); c.start(); } } catch (java.io.IOException e) { System.out.println(e); } } 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()); try { 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 ver. • 윈도우 소켓(Window socket)은 유닉스에서 사용되는 BSD소켓을 계승하기 때문에 윈속에서 사용되는 대부분의 함수와 구조체는 유닉스 버전과 동일하다. 그러나 윈속을 사용하기 전에 유닉스와 달리 윈속 라이브러리를 초기화 해주고 사용이 끝나면 해제를 시켜줘야 한다. • 초기화 : WSAStartup, 해제 : WSACleanup • talk_client, talk_server • 유닉스 버전 : 키보드 입력과 데이터 수신 처리를 fork를 이용해서 분기 • 윈도우 버전 : 키보드 입력은 메인에서, 데이터수신 처리는 쓰레드를 이용 • chat_client, chat_server • 유닉스 버전 : select를 사용하여 데이터 I/O를 비동기적으로 처리, 키보드 입력은 fork를 이용 • 윈도우 버전 : I/O방식은 쓰레드에서 select를 사용, 키보드 입력은 메인에서 처리