네트워크 프로그래밍 2001. 12. 06 Youngnam Kim
목 차 10.1 TCP/IP 이해 10.2 소켓 10.3 간단한 소켓 프로그램들 10.4 DatagramSocket
10.1 TCP/IP 이해 Application Presentation Session Transport Network Datalink Physical 7:e.g.,: TELNET, HTTP 6:e.g.,: XNS 5:e.g.,: RPC 4:e.g.,: TCP, UDP 3:e.g.,: IP, Aapplet Talk 2:e.g.,: Ethernet frames 1:e.g.,: voltages [그림 10-1] OSI 7계층
10.1 TCP/IP 이해(Cont.) TCP/IP : TCP와 IP 관련 프로토콜(ex. UDP,ARP,ICMP) 및 응용프로그램(ex. TELNET, FTP)의 통칭. < 전송되는 데이터들의 TCP/IP프로토콜 계층에 의해 불리는 이름 > Ethernet frame: 이더넷 계층 IP packet(or IP datagram): 이더넷 드라이버와 IP모듈 사이 UDP datagram: IP 모듈과 UDP 모듈사이 TCP segment(or transport message): IP 모듈과 TCP 모듈사이
< http://java.sun.com/index.html 방문시> 10.1 TCP/IP 이해(Cont.) < http://java.sun.com/index.html 방문시> 웹브라우저가 HTTP요청 -> 캡슐화(encapsulation) -> java.sun.com 컴퓨터에 데이터 전달 -> 역캡슐화(decapsulation) -> java.sun.com의 웹서버 프로그램에 전달 -> 웹서버가 요청처리 HTTP요청 “GET /index.html HTTP/1.0” TCP 세그먼트 IP 패킷 이더넷 프레임 네트워크 라인 캡슐화 TCP헤더 “GET /index.html HTTP/1.0” IP헤더 TCP헤더 “GET /index.html HTTP/1.0” 이더네헤더 IP헤더 TCP헤더 “GET /index.html HTTP/1.0” 역캡슐화
10.1 TCP/IP 이해(Cont.) TCP UDP IP ARP Ethernet Network Card [그림 10-4] 네트워크에 연결된 컴퓨터 이더넷 프레임 도달 -> Frame의 type 필드값에 따라 ARP나 IP모듈로 전달 (IP모듈이면 protocol필드값에 따라 TCP모듈이나 UDP모듈로 데이터 전송)
10.1 TCP/IP 이해(Cont.) 1. 이더넷 사용하는 경우 네트워크내에서 브로드캐스트된다. 203.253.23 네트워크 203.253.24 203.253.23.1 203.253.23.3 203.253.23.2 203.253.24.95 Router [그림 10-7] 네트워크 구성 1. 이더넷 사용하는 경우 네트워크내에서 브로드캐스트된다. 2. 각 컴퓨터는 자신에게 온 데이터인지 여부를 IP주소가 아닌 이더넷 주소보고 판단한다.(ARP이용)
10.1 TCP/IP 이해(Cont.) 네트웤이 다른 경우 라우터 이용: UDP IP ARP Ethernet Network Card [그림 10-8] 라우터 역할을 하는 컴퓨터 203.253.23 네트워크 203.253.24 네트워크 네트웤이 다른 경우 라우터 이용: 라우터는 받은 데이터를 역캡슐화하여 라우터 자신의 IP가 아니면 해당 네트웤에 데이터 전달한다.
10.2 소켓 10.2.1 소켓 소개 10.2.2 채팅 프로그램 10.2.3 화이트보드 작성 10.2.4 멀티 룸 채팅 프로그램
10.2.1 소켓 소개 포트번호 : 트랜스포트 계층에서 사용되는 주소와 같은 것 10.2.1 소켓 소개 포트번호 : 트랜스포트 계층에서 사용되는 주소와 같은 것 소켓 : TCP/IP 네트워크에서 양쪽 응용프로그램의 TCP연결 응용 프로그램 InputStream OutputStream 호스트 컴퓨터 포트 네트워크 IP 어드레스 소켓 [그림 10-9] IP, 포트, 소켓
(TCP three-way handshake 10.2.1 소켓 소개 (Cont.) socket() connect() write() read() close() bind() listen() accept() TCP 클라이언트 TCP 서버 연결됨 (TCP three-way handshake end-of-file 마크 데이터(응답) 데이터(요청) 클라이언트 요청처리 클라이언트로부터 연결될 때까지 블락됨 [그림 10-10] C 언어에서 TCP 프로그램 작성
10.2.1 소캣 소개(Cont.) <생성자> ServerSocket(int port) 네트워크 프로그래밍을 위해서는 java.net 패키지를 이용해야 한다. ServerSocket 클래스: C에서의 소켓만들고, bind(), listen()의 반복작업 제거하기 위해 만들어진 클래스로 서버측에서 사용. <생성자> ServerSocket(int port) ServerSocket(int port, int backlog) ServerSocket(int port, int backlog, InetAddress bindAddr) port : 서버 소켓이 사용할 포트 번호. 0~216-1사이값가능하나 0~1023은 보통 시 스템에서 사용목적으로 예약되어 있다. backlog : 클라이언트의 동시 connection요청을 기록할 최대수. 즉, 큐의 최대길이. bindAddr: 서버프로그램이 여러개인 컴퓨터에서 작동되는 경우에 각 컴퓨터에서 connection을 만드는 것이 아니라 특정한 컴퓨터의 포트만 이용해서 connection이 이루어지도록 할때 사용.
10.2.1 소캣 소개(Cont.) <생성자> Socket(String host, int port) Socket 클래스 : C에서의 connect()라는 함수 호출하지 않기위해 만들어진 클래스로, 클라이언트에서 사용. <생성자> Socket(String host, int port) Socket(InetAddress address, int port) host : 컴퓨터의 이름 port : 포트 번호 address : IP 어드레스 <소켓을 만든 후 데이터 주고받기 위해 I/O 스트림 만들기> 데이터 전송 위해 : getOutputStream()통해 OutputStream얻기. 데이터 받기 위해 : getInputStream()통해 InputStream얻기.
10.2.1 소캣 소개(Cont.) [그림 10-11] 자바 언어에서 TCP 프로그램 작성 TCP 서버 TCP 클라이언트 socket() I/O 스트림 생성 write() read() close() I/O 스트립 생성 Serversocket() accept() [그림 10-11] 자바 언어에서 TCP 프로그램 작성 TCP 클라이언트 TCP 서버 클라이언트로부터 연결될 때까지 블락됨 데이터(응답) 데이터(요청) 연결됨
10.2.2 채팅 프로그램 채팅서버 : 클라이언트 접속 -> TCP연결만들어줌 / 채팅 클라이 언트 리스트에 등록 -> 다른 클라이언트의 접속을 기다림 ChatHandler: 클라이언트로부터 메시지 받아 다른 클라이언트에 게 전달해주는 프로그램.그러므로, 각 클라이언트마다 ChatHandler 클래스가 있어야 한다. 채팅 클라이언트: 소켓 생성 -> I/O 스트림 생성 -> 사용자 입력을 서버에 전달 & 서버로부터의 메시지를 화면에 출력
10.2.2 채팅 프로그램 ChatServer ChatApplet ChatHandler 10.2.2 채팅 프로그램 ChatHandler ChatServer ChatApplet [그림 10-12] ChatServer, ChatHandler, ChatApplet 관계
10.2.2 채팅 프로그램(Cont.) ChatServer.java : 채팅 클라이언트가 접속해 오면 클라이언트에 매칭되는 ChatHandler를 만들어 handlers라는 벡터에 등록시키고 다른 클라이언트의 접속을 기다리는 채팅서버 프로그램. import java.net.*; import java.util.*; public class ChatServer { private boolean debug = false; protected Vector handlers; public ChatServer (int port) { try { ServerSocket server = new ServerSocket (port); handlers = new Vector(); System.out.println("ChatServer is ready.");
while (true) { Socket client = server.accept (); if(debug) System.out.println ("From: "+ client.getInetAddress()); ChatHandler c = new ChatHandler (this, client); handlers.addElement(c); c.start (); } } catch(Exception e) { e.printStackTrace(); } } public static void main (String args[]) { if (args.length != 1) new ChatServer(9830); else new ChatServer(Integer.parseInt(args[0]));
10.2.2 채팅 프로그램(Cont.) ChatHandler.java : ChatServer로부터 넘겨받은 소켓을 이용해서 I/O 스트림 생성 -> 클라이언트의 메시지는 ChatHandler의 PrintWriter를 통해 ChatHandler에 전달 -> handlers를 이용하여 모든ChatHandler에 메시지 전달 import java.net.*; import java.io.*; import java.util.*; public class ChatHandler extends Thread { private boolean debug = false; protected Socket s; protected BufferedReader i; protected PrintWriter o; protected ChatServer server; protected boolean stop; public ChatHandler(ChatServer server, Socket s) throws IOException { this.s = s; this.server = server; InputStream ins = s.getInputStream(); OutputStream os = s.getOutputStream(); i = new BufferedReader(new InputStreamReader(ins)); o = new PrintWriter(new OutputStreamWriter(os)); }
public void setStop() { stop = true; synchronized(server.handlers) { server.handlers.remove(this); } public void run () { String name = ""; try { name = i.readLine(); broadcast (name + "님이 방문하셨습니다."); while (!stop) { String msg = i.readLine(); if(msg.equals("!#%&")) { setStop(); } else { broadcast (name + " - " + msg); } catch (IOException ex) { if(debug) ex.printStackTrace(); } finally { server.handlers.removeElement(this); broadcast (name + "님이 나가셨습니다."); try { i.close(); o.close(); s.close(); }
protected void broadcast (String message) { synchronized (server.handlers) { int n = server.handlers.size(); for(int i=0; i < n; i++) { ChatHandler c = (ChatHandler) server.handlers.elementAt(i); try { synchronized (c.o) { c.o.println(message); } c.o.flush (); } catch (Exception ex) { c.setStop();
10.2.2 채팅 프로그램(Cont.) ChatApplet.java : 소켓 생성 -> I/O 스트림 생성 ->서버로 전달및 전달받은 내용 화면 출력 쓰레드1: 사용자의 입력을 서버측에 전달 쓰레드2: 서버로부터 전달되는 메시지 읽어 화면에 출력 import java.net.*; import java.io.*; import java.awt.*; import java.awt.event.*; import java.applet.*; public class ChatApplet extends Applet implements Runnable, ActionListener { private boolean debug = false; protected BufferedReader i; protected PrintWriter o; protected TextArea output; protected TextField input, logtext; protected Thread listener; protected CardLayout card; protected boolean stop; public void init () { card = new CardLayout(); setLayout (card); Panel login = new Panel(new BorderLayout()); Panel bottom = new Panel(); logtext = new TextField(15); logtext.addActionListener(this);
bottom.add(new Label("로그인:")); bottom.add(logtext); login.add("South", bottom); login.add("Center", new Label("자바 애플릿 채 팅", Label.CENTER)); Panel chat = new Panel(new BorderLayout()); chat.add ("Center", output = new TextArea ()); output.setEditable (false); chat.add ("South", input = new TextField ()); input.addActionListener(this); add(login, "login"); add(chat, "chat"); card.show(this, "login"); } public void start () { stop = false; listener = new Thread (this); listener.start (); public void stop () { if (listener != null) { stop = true; try { if(o != null) { o.println("!#%&"); o.flush(); i.close(); o.close(); } } catch (Exception e) { } listener = null; public void destroy() { stop();
public void run () { try { String host = getCodeBase().getHost (); String port = getParameter ("port"); if (port == null) port = "9830"; Socket s = new Socket (host, Integer.parseInt (port)); InputStream ins = s.getInputStream(); OutputStream os =s.getOutputStream(); i = new BufferedReader(new InputStreamReader(ins)); o = new PrintWriter(new OutputStreamWriter(os)); execute (); } catch (IOException ex) { if(debug) ex.printStackTrace (System.out); } public void execute () { try { while (!stop) { String line = i.readLine(); output.append (line + "\n"); } } catch (IOException ex) { if(debug) ex.printStackTrace (System.out); } finally { listener = null; o.close();
public void actionPerformed (ActionEvent e) { Component c = (Component) e.getSource(); if(c == logtext) { String loginname = logtext.getText(); loginname = loginname.trim(); if(loginname == null || loginname.length() == 0) { return; } o.println(loginname); o.flush(); card.show(this, "chat"); input.requestFocus(); } else if(c == input) { o.println(input.getText()); o.flush (); input.setText ("");
10.2.2 채팅 프로그램(Cont.) F:\>appletviewer ChatApplet.html
10.2.3 화이트보드 작성 화이트보드: 채팅 프로그램의 변경. 인터넷상에서 공동으로 그림을 그릴 수 있는 화이트보드. 10.2.3 화이트보드 작성 화이트보드: 채팅 프로그램의 변경. 인터넷상에서 공동으로 그림을 그릴 수 있는 화이트보드. 마우스를 클릭, 드래그하면 마우스의 위치정보가 서버에 전달 -> 서버는 메시지를 모든 클라이언트에 전달 -> 클라이언트는 메시지 해석후 도형으로 변환하여 화면에 보여줌. WhiteServer.java : 채팅 서버와 동일 WhiteHandler.java : ChatHandler와 달리 전달받은 메시지를 그대로 클 라이언트에게 전달 WApplet.java : 텍스트 영역대신 Canvas 클래스 상속받은 Wcanvas 클래스를 사용. 화이트 보드 서버에서 읽어 온 정보를 Wcanavas에 전달
10.2.3 화이트보드 작성 (Cont.) Wcanvas.java addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); String msg = mode + ":" + x + ":" + y + ":"+ 20 +":"+ 15; switch(mode) { case NONE: return; case LINE: tempX = x; tempY = y; break; case RECT: send(msg); } });
10.2.3 화이트보드 작성 F:\>appletviewer Wapplet.html
10.2.4 멀티 룸 채팅 프로그램 멀티룸 채팅 프로그램:방이 여러개인 채팅 프로그램. 10.2.4 멀티 룸 채팅 프로그램 멀티룸 채팅 프로그램:방이 여러개인 채팅 프로그램. MCahtServer.java : 채팅 서버를 위한 클래스 Handler에 parameter로, 자신의 object대신 MRoomManager object를 넘긴다. ChatHandler c = new ChatHandler (this, client); -> MCahtHandler c = new MChatHandler(manager, client); MChatRoom.java : 채팅 방을 표현하기 위한 클래스 채팅방 이름(name), 채팅 방에 소속된 클라이언트를 저장하기 위한 벡터 멤버 필드(handlers)를 갖고 있다. MRoomManager.java : 새로운 채팅방을 만들고, 현재 등록된 채팅 방들의 이름을 알아보며 채팅방 관리하는 클래스 - (처음) ‘$#!@라운지’ -> (방선택) ‘$#!@라운지’ 에서 클라이언트 삭제 -> 채팅방에 MChatHandler를 추가 -> (방나감) 채팅방의 MChatHandler삭제 -> ‘$#!@라운지’ 방에 MChatHandler추가
10.2.4 멀티 룸 채팅 프로그램(Cont.) MCahtHandler.java : ChatHandler와 유사하지만, 다음의 특수 채팅 메시지를 갖고 있다. #!u+ : 새로운 사용자 추가 #!u- : 사용자 제거 !#$ : 귓속말 기능 !#r- : 채팅 방을 빠져나감 !#r+ : 채팅방에 들어감 !#r* : 전체 채팅 방 목록을 요청함 !#rc : 새로운 채팅 방을 만듬 !#u* : 채팅 방에 소속된 사용자들이 목록을 요청함 McahtApplet.java : ChatApplet과 와 유사하지만, 멀티 룸 채팅할 수 있는 화면과 기능 제공.
10.2.4 멀티 룸 채팅 프로그램(Cont.) MChatRoom.java public void broadcast(String msg) { synchronized(handlers) { Enumeration e =handlers.elements(); if(debug) System.out.println("# of user:"+handlers.size()); while (e.hasMoreElements()) { MChatHandler c = (MChatHandler) e.nextElement(); c.o.println(msg); c.o.flush (); } public MChatHandler getHandler(String name){ synchronized(handlers) { int n = handlers.size(); for(int i=0; i < n; i++) { MChatHandler c = (MChatHandler)handlers.elementAt(i); if(name.equals(c.name)) { return c; } return null;
10.2.4 멀티 룸 채팅 프로그램(Cont.) MChatRoom.java public MChatRoom getChattingRoom(String name) { synchronized(rooms) { int n = rooms.size(); for(int i=0; i < n; i++) { MChatRoom c = (MChatRoom) rooms.elementAt(i); if(name.equals(c.name)) { return c; } return null; public MRoomManager() { rooms = new Vector(); lounge = new MChatRoom("$#!@라운지"); } public void createRoom(String name) { rooms.add(new MChatRoom(name)); lounge.broadcast(getAllRoomNamesString()); }public void removeRoom(String name) { synchronized(rooms) { int n = rooms.size(); for(int i=0; i < n; i++) { MChatRoom c = (MChatRoom) rooms.elementAt(i); if(name.equals(c.name)) { rooms.remove(c); …..
10.2.4 멀티 룸 채팅 프로그램 F:\>appletviewer MChatApplet.html
10.3 간단한 소켓 프로그램들 10.3.1 ping 프로그램 10.3.2 Network News Transfer Protocol(NNTP) 10.3.3 SMTP(Simple Mail Transfer Protocol) 10.3.4 Post Office Protocol - Version 3(POP3)
10.3.1 ping 프로그램 유닉스/ 도스 ping 프로그램: 네트워크로 연결된 다른 컴퓨터가 현재 작동 중인지 알아보는 프로그램.ICMP 프로토콜을 사용하므로 자바를 이용해서 프로그래밍 할 수 없다. Ping.java : 유닉스의 echo 프로토콜 사용(7번 포트) 소켓 만들어 서버에 메시지 보냄 -> 서버로부터 메시지 받음 -> 보낸 메시지와 동일하면 작동중. F:\>java Ping 203.252.206.1 Alive :-)
import java.io.*; import java.net.*; class Ping { public static void main(String args[]) { try { Socket t = new Socket(args[0], 7); BufferedReader is = new BufferedReader(new InputStreamReader(t.getInputStream())); PrintStream os = new PrintStream(t.getOutputStream()); os.println("Hello"); String str = is.readLine(); if ("Hello".equals(str)) System.out.println("Alive :-)") ; else System.out.println("Dead :-("); t.close(); } catch (Exception e) { System.out.println(e); }
10.3.2 NNTP(Network News Transfer Protocol) 뉴스의 배포, 포스팅, 검색에 관련된 프로토콜. 중앙의 DB에 뉴스기사들 저장하고, 독자들이 원하는 기사 읽음. 뉴스 그룹은 주제별로 분류되어 있고, 각 주제에 맞는 내용을 포스팅 119번 포트 사용 NNTP명령어 ARTICLE : 뉴스 기사를 읽어오는 명령어. ARTICLE <message-id> ARTICLE [mm] GROUP : 뉴스 그룹 설정. GROUP groupname
NNTP명령어 (Cont.) HELP : 도움말 HELP IHAVE : 클라이언트가 뉴스기사를 가지고 있는 것을 서버에 알림 IHAVE <messageid> LIST : 사용 가능한 뉴스 그룹들의 목록 LIST NEWNEWS : date와 time에 기술된 시간이후에 게시된 새로운 뉴스들의 id를 보여준다. NEWNEWS newsgroup date time [GMT] NEXT : 다음뉴스로 포인트를 이동시킨다. NEXT POST :뉴스 기사를 포스팅 POST QUIT : 뉴스서버와 연결 종료 QUIT
10.3.2 NNTP (Cont.) Telnet을 이용한 뉴스 읽고 포스팅하기 뉴스 읽는 프로그램 작성
10.3.2 NNTP (Cont.) 뉴스 읽는 프로그램 작성(Cont.) NntpHeader.java: 썬의 sun.net.nntp패키지를 이용해서 작성 for (int i = first; i <= last; i++) { try { InputStream theHeader = c.getHeader(i); BufferedReader br = new BufferedReader(new InputStreamReader(theHeader)); String theLine; System.out.println("---------------- -\nHeader " + i + "/" + last); while ((theLine = br.readLine()) != null) System.out.println(theLine); } catch (NntpProtocolException ne) { } } } } import sun.net.nntp.*; import java.io.*; public class NntpHeader { public static void main(String[] args) throws IOException { NntpClient c = new NntpClient(args[0]); String newsgroup = "han.test"; c.setGroup(newsgroup); NewsgroupInfo ni =c.getGroup(newsgroup); int first = ni.firstArticle; int last = ni.lastArticle;
10.3.2 NNTP (Cont.) 뉴스 읽는 프로그램 작성(Cont.) NewsHeader.java: 소켓을 이용하여 뉴스그룹의 제목만 출력하는 프로그램 import java.io.*; import java.net.*; public class NewsHeader { public static void main(String args[]) { PrintStream out; BufferedReader in; String line = null; if(args.length != 1) return;
F:\>java NewsHeader news.nuri.net 무료 종합 공개견적 사이트 오픈!!! try { Socket socket = new Socket(args[0], 119); out = new PrintStream(socket.getOutputStream()); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out.println("GROUP han.test"); out.flush(); while(line == null || !line.startsWith("421")) { out.println("HEAD"); line = in.readLine(); if(line.startsWith("Subject: ")) { System.out.println(line.substring(9)); } out.println("NEXT"); out.flush(); } catch(Exception e) { System.out.println(e); } } F:\>java NewsHeader news.nuri.net 무료 종합 공개견적 사이트 오픈!!! 인터넷 무료 종합 견적 서비스 소개합니다! ……………
10.3.2 NNTP (Cont.) NewsReader.java: 전체적으로 뉴스 그룹 선택, 제목읽기, 내용읽기, 포스팅 가능한 프로그램 (교재 p.637 – p.643) private void getNewsBody(String id) { display.setText(""); PrintStream out = null; try { String line = ""; Socket s = new Socket(serverName, 119); out = new PrintStream(s.getOutputStream()); BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); out.println("GROUP " + group.getSelectedItem()); out.flush(); out.println("BODY " + id) ; while(true) { line = in.readLine(); if(line.startsWith(".")) break; else display.append(line +"\n"); } out.println("QUIT"); out.flush(); } catch(Exception e) { System.out.println(e); out.println("QUIT"); out.flush(); } }
10.3.2 NNTP (Cont.)
10.3.3 SMTP(Simple Mail Transfer Protocol) SMTP: 메일을 효과적이고 신뢰성있게 전송하기 위한 프로토콜 (RFC 821) [그림 10-20] SMTP 구성 < sender-SMTP와 receiver-SMTP의 상호 대화방식의 메일 전달> sender-SMTP입장에서: 사용자 메일요청 -> receiver-SMTP와 양방향 전송 채널만듦 -> MAIL 명렁어를 receiver-SMTP에 보냄 ->OK받으면 RCPT 명렁어로 수진자 알려줌 ->수신자에게 메일 보낼 수 있다는 OK메시지 받으면 메일전달
10.3.2 SMTP (Cont.) SMTP 명령어 HELO : sender-SMTP와 receiver-SMTP 간에 전송 채널만듦 HELO <SP> <domain> <CRLF> MAIL : receiver-SMTP에 메일을 보낼 것이라고 알리고, 보내는 사람의 메일 주 소 기입 MAIL <SP> FROM: <reverse-path> <CRLF> RCPT : 메일 수신자 RCPT <SP> TO: <forward-path> <CRLF> DATA : 메일 내용을 receiver-SMTP 에 전송. 메일의 끝에 ‘.’ DATA <CRLF> QUIT :전송채널을 닫음 QUIT <CRLF>
10.3.2 SMTP (Cont.) telnet을 이용해서 메일 보내기
10.3.4 Post Office Protocol – Version 3 (POP3) POP3 : TCP 포트 110 사용하면서, 클라이언트의 요청과 서버의 응답이라는 상호 대화 방식으로 서비스 해준다. 서버의 응답에는 서버의 상태를 표시하는 메시지 포함(성공: +OK,실패: -ERR) POP3 명령어 USER : POP3 서버에 사용자 id 전달 USER user_name PASS : POP3 서버에 사용자의 암호 전달 PASS password QUIT : TCP 연결을 끊으면서 삭제 마크가 있는 경우에 메일을 삭제 QUIT
POP3 명령어 (Cont.) STAT : 상태를 알려줌. STAT 명령어의 응답은 “+OK nn mm”형태 (nn: 메일의 개수, mm: 메일의 크기) STAT LIST : 메일의 리스트 보여줌. 메시지 번호 부여 가능 LIST [msg#] RETR : 메일의 내용을 보여줌. 해당 번호 부여 가능 RETR msg# DELE : 메일 삭제 마크를 붙임 DELE msg# NOOP : 아무 작업도 하지 않음 NOOP RSET : POP3의 메일 상태를 초기화. 삭제 마크도 없어짐. RSET
10.3.4 POP3 (Cont.) POP3 응답 +OK -ERR telnet을 이용한 메일 읽기
MailReader : 메일을 읽고 보내는 프로그램 10.3.4 POP3 (Cont.) MailReader : 메일을 읽고 보내는 프로그램 <SMTP와 POP3 이용> (교재 p.650 – p.661) 다이얼로그 창으로 서버지정 -> id와 passwd입력 -> POP3이용하여 서버로부터 메일을 가져옴 “Send Mail”버튼 클릭 -> 메일 보낼 수 있는 화면 -> 내용입력-> “SEND”버튼 클릭 -> SMTP 프로토콜 이용하여 메일 전송 try { Socket s = new Socket(serverName, 110); in = new BufferedReader(new InputStreamReader(s.getInputStream())); out = new PrintStream(s.getOutputStream()); String incoming = in.readLine(); out.println("USER " + user); out.flush(); POP3 연결부분 incoming = in.readLine(); out.println("PASS " + passwd); out.flush(); incoming = in.readLine(); if(incoming.startsWith("-ERR")) { System.out.println("Password is not correct!!"); ……….
10.3.4 POP3 (Cont.) Body의 내용가져오는 부분 out.println("RETR "+(list.getSelectedIndex()+1));out.flush(); String incoming = in.readLine(); if(incoming.startsWith("-ERR")) { out.println("QUIT"); out.flush(); return; } Body의 내용가져오는 부분 incoming = in.readLine(); while(!incoming.equals(".")) { display.append(incoming+"\n"); } out.println("QUIT"); out.flush();
10.3.4 POP3 (Cont.) MailReader (Cont.)
10.4 DatagramSocket TCP UDP 신뢰성 있다. 없다 자원소모 많다. 적다. UDP사용: 클라이언트, 서버 모두 DatagramSocket클래스 만들고, 그것을 이용해 패킷단위로 정보이동.
10.4 DatagramSocket (Cont.) UDP 클라이언트 UDP 서버 send() receive() close() 클라이언트 요청 처리 데이터(응답) 데이터(요청) [그림 10-23] 자바 UDP 프로그램 작성
10. 4 DatagramSocket (Cont.) DatagramSocket(int port) : 로컬 컴퓨터의 주어진 포트 사용 DatagramSocket(int port, InetAddress addr) : 주어진 주소와 포트 사용 DatagramPacket 생성자 데이터를 받는 경우에 사용되는 생성자 DatagramPacket(byte[] buf, int length) DatagramPacket(byte[] buf, int offset, int length) 데이터를 보내는 경우에 사용되는 생성자 DatagramPacket(byte[] buf, int length, InetAddress address, int port) DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
10. 4 DatagramSocket (Cont.) DatagramServerThread.java private DatagramSocket socket = null; DatagramServerThread() { ……… socket = new DatagramSocket(1268); ……… try{ ……… packet = new DatagramPacket(buf, 1024); socket.receive(packet); int len = packet.getLength(); address = packet.getAddress(); port = packet.getPort(); showMessage(buf, len); } catch (IOException e) {………
10. 4 DatagramSocket (Cont.) DatagramClient.java protected void sendMessage() { try { address = InetAddress.getByName(serverName); socket = new DatagramSocket(); } catch(Exception e) { System.out.println(e); } if (socket != null) { try { String msg = input.getText(); byte[] buf = msg.getBytes(); packet = new DatagramPacket(buf, buf.length, address, 1268); socket.send(packet); ………
10. 4 DatagramSocket (Cont.) DatagramClient.java (Cont.) public void sendMessage() { ………. if (socket != null) { try { String msg = input.getText(); byte[] buf = msg.getBytes(); packet = new DatagramPacket(buf, buf.length, address, 1268); socket.send(packet); } catch (IOException e) { System.err.println("IOException: " + e); e.printStackTrace(); } socket.close(); public void actionPerformed(ActionEvent e) { Button b = (Button) e.getSource(); if(b == send) { serverName = server.getText(); if(serverName == null || serverName.trim().length() == 0) return; sendMessage(); input.setText(""); } else { }
10. 4 DatagramSocket (Cont.) 실행결과