'imap'에 해당되는 글 3건

  1. 2010.01.27 JavaMail with IMAP
  2. 2010.01.27 IMAP과 POP의 비교
  3. 2009.09.21 Post Office Protocol(POP3)
프로그래밍/JAVA2010. 1. 27. 11:03
JavaMail1.4.3은 IMAP4와 IMAP4rev1을 지원하며, IMAP의 주요 특성을 요약하면 다음과 같다.

  • 지속적으로 메세지 상태 플래그를 처리할 수 있다. 이러한 플래그에는 SEEN, DELETE, ANSWERED, RECENT 등이 있다.
  • 여러 편지함을 관리하고 접근할 수 있다. 받은 편지함과 다른 편지함에 접근하고 이름짓는 기능이 있기 때문에 가능하며 이들의 목록을 보고, 편지함을 생성, 삭제하고 이름을 바꾸는것도 가능하다.
  • 메일내용을 가져올 뿐만 아니라 저장할 수 있다. 사용자의 임의의 편지함으로부터 원하는 편지함으로 메일을 이동시킬 수 있다.
  • 메일 이외의 데이터도 접합하다. 이러한 기능은 서로 다른 정보를 동일한 방법으로 접근할 때 편리하다.
  • 온라인 성능을 최적화(특히 저속 링크일 경우)할 수 있다. 이것은 메세지 다운로드 없이 메세지 구조 가져오기 기능, 선택적으로 부분 메세지를 가져오는 기능, 클라이언트와 서버사이의 데이터 전송량을 줄이기 위해 서버를 검색하는 기능을 포함한다. 특히 작은 대역폭을 가지는 전송로를 통하여 메일 서버에 접속하고 있을 때 전송 메세지와 바로 필요하지 않는 메세지를 분리할 수 있다는 것은 아주 유용하다.

다음은 IMAP과 POP의 접근에 공통된 인터페이스를 제공하기 위한 선언이다.
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Store;

public interface MailProto {

	abstract public void open(String host, String id, String passwd) throws MessagingException;
	
	abstract public void close() throws MessagingException;
	
	abstract public Message getMessages(int msgNum) throws MessagingException;
	
	abstract public Message[] getMessages() throws MessagingException;
	
	abstract public Message[] getRecentMessages(int count) throws MessagingException;
	
	abstract public int getMessageCount() throws MessagingException;
	
	abstract public String getUID(Message msg) throws MessagingException;
	
	abstract public Folder getFolder() throws MessagingException;
	
	abstract public Store getStore() throws MessagingException;
}
다음은 MailProto 인터페이스를 사용한 IMAP 구현체이다.
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.URLName;

import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;

public class IMAP implements MailProto {
	
	protected Session session;
	
	protected Store store;
	
	protected Folder folder;
	
	private static String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
	
	@Override
	public void open(String host, String id, String passwd) throws MessagingException {
		Properties props = new Properties();
		props.setProperty("mail.imap.socketFactory.class", SSL_FACTORY);
		props.setProperty("mail.imap.socketFactory.fallback", "false");
		props.setProperty("mail.imap.port", "993");
		props.setProperty("mail.imap.socketFactory.port", "993");
		session = Session.getInstance(props, null);
		URLName urlName = new URLName("imap", host, 993, "", id, passwd);
		store = new IMAPStore(session, urlName);
		store.connect();
		folder = store.getDefaultFolder().getFolder("INBOX");
		folder.open(Folder.READ_WRITE);
	}
	
	@Override
	public void close() throws MessagingException {
		if( folder != null && folder.isOpen() )
			folder.close(true);
		if( store != null && store.isConnected() )
			store.close();
	}
	
	@Override
	public Message getMessages(int msgNum) throws MessagingException {
		if( !folder.isOpen() )
			throw new MessagingException("Already closed folder");
		return folder.getMessage(msgNum);
	}
	
	@Override
	public Message[] getMessages() throws MessagingException {
		if( !folder.isOpen() )
			throw new MessagingException("Already closed folder");
		return folder.getMessages();
	}
	
	@Override
	public Message[] getRecentMessages(int count) throws MessagingException {
		if( !folder.isOpen() )
			throw new MessagingException("Already closed folder");
		int folderSize = folder.getMessageCount();
		return folder.getMessages(folderSize-count+1, folderSize);
	}
	
	@Override
	public int getMessageCount() throws MessagingException {
		if( !folder.isOpen() )
			throw new MessagingException("Already closed folder");
		return folder.getMessageCount();
	}
	
	@Override
	public String getUID(Message msg) throws MessagingException {
		if( folder instanceof IMAPFolder ) {
			return new Long(((IMAPFolder)folder).getUID(msg)).toString();
		}
		else {
			throw new MessagingException("Can not support");
		}
	}

	@Override
	public Folder getFolder() throws MessagingException {
		if( !folder.isOpen() )
			throw new MessagingException("Already closed folder");
		return folder;
	}

	@Override
	public Store getStore() throws MessagingException {
		if( !store.isConnected() )
			throw new MessagingException("Already closed store");
		return store;
	}
}
다음은 MailProto 구현체의 호스트 클래스로서 IMAP과 POP에 모두 공통적으로 이용할 수 있다.
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Store;

public class MailAgent {

	protected MailProto mailProto;
	
	protected String host;
	
	protected String id;
	
	protected String passwd;
	
	public MailAgent(MailProto mailProto, String host, String id, String passwd) {
		if( mailProto == null || host == null || id == null || passwd == null )
			throw new IllegalArgumentException();
		this.mailProto = mailProto;
		this.host = host;
		this.id = id;
		this.passwd = passwd;
	}
	
	public void open() throws MessagingException {
		mailProto.open(host, id, passwd);
	}
	
	public void close() throws MessagingException {
		mailProto.close();
	}
	
	public Message getMessage(int msgNum) throws MessagingException {
		return mailProto.getMessages(msgNum);
	}
	
	public Message[] getMessage() throws MessagingException {
		return mailProto.getMessages();
	}
	
	public Message[] getRecentMessages(int count) throws MessagingException {
		return mailProto.getRecentMessages(count);
	}
	
	public String getUID(Message msg) throws MessagingException {
		return mailProto.getUID(msg);
	}
	
	public int getMessageCount() throws MessagingException {
		return mailProto.getMessageCount();
	}
	
	public Folder getDefaultFolder() throws MessagingException {
		return mailProto.getFolder();
	}
	
	public Store getStore() throws MessagingException {
		return mailProto.getStore();
	}
	
	public MailProto getMailProto() {
		return mailProto;
	}
	
	public void setMailProto(MailProto mailProto) {
		this.mailProto = mailProto;
	}
}
다음은 MailAgent를 상속하여 POP과는 차별되는 IMAP의 고유 기능을 지원하기 위한 클래스이다.
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Flags.Flag;
import javax.mail.search.FlagTerm;

public class IMAPAgent extends MailAgent {
	
	public IMAPAgent(String host, String id, String passwd) {
		super(new IMAP(), host, id, passwd);
	}
	
	public Folder getFolder(String name) throws MessagingException {
		return getStore().getFolder(name);
	}
	
	public Message[] getUnReadMessages() throws MessagingException {
		return getDefaultFolder().search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
	}
	
	public void createFolder(String name) throws MessagingException {
		Folder folder = getStore().getFolder(name);
		if( !folder.exists() ) {
			folder.create(Folder.HOLDS_MESSAGES);
		}
	}
	
	public void moveMessage(Message[] message, Folder src, Folder dest) throws MessagingException {
		src.copyMessages(message, dest);
		src.setFlags(message, new Flags(Flags.Flag.DELETED), true);
	}
	
	public void setSeenFlag(Message message) throws MessagingException {
		setFlags(message, Flags.Flag.SEEN, true);
	}
	
	public void setUnSeenFlag(Message message) throws MessagingException {
		setFlags(message, Flags.Flag.SEEN, false);
	}
	
	public void setFlags(Message message, Flag flag, boolean set) throws MessagingException {
		message.setFlag(flag, set);
	}
	
	public boolean hasNewMessage(Folder folder) throws MessagingException {
		return folder.hasNewMessages();
	}	
}
다음은 IMAP 서버에 접속하여 읽지않은 메일을 읽음으로 표시하고 newFolder라는 곳으로 메일을 이동시키는 예제이다.
public static void readEmail() throws Exception {
		IMAPAgent mailagent = new IMAPAgent("pop.hanmail.net", "주소@hanmail.net", "비밀번호");
		mailagent.open();
		mailagent.createFolder("newFolder");
		Message[] msg = mailagent.getUnReadMessages();
		for(Message m : msg) {
			System.out.println("subject: "+m.getSubject());
			System.out.println("MsgNum: "+m.getMessageNumber());
			System.out.println("UID: "+mailagent.getUID(m));
			System.out.println("Sent Date: "+m.getSentDate());
			mailagent.setSeenFlag(m);
		}
		mailagent.moveMessage(msg, mailagent.getDefaultFolder(), mailagent.getFolder("newFolder"));
		mailagent.close();
	}
다음은 위 메세드를 실행하기전 메일함의 모습이다. 2개의 메일중 하나가 읽지 않음 상태에 있으며, newFolder는 존재하지 않는다.


메서드를 실행하면 메일함은 다음과 같이 변경된다. 읽지않음 메일은 읽음으로 상태 플래그가 변경되었으며, newFolder라는 새로운 폴더가 생성되었고 이 폴더로 메일이 이동되었다.


'프로그래밍 > JAVA' 카테고리의 다른 글

Java 어노테이션(Annotation)  (0) 2010.04.21
Java Decompiler jad  (2) 2010.03.17
Apache Xml Security을 이용한 XML 전자서명  (1) 2010.03.17
MSSQL with JDBC  (0) 2010.02.03
JavaMail 첨부파일 읽기  (0) 2010.01.28
JavaMail with IMAP  (0) 2010.01.27
JavaMail을 이용하며 메일전송  (0) 2010.01.15
RSA 암호화  (0) 2010.01.15
Java 쓰레드  (0) 2009.12.04
스트러츠 properties 한글 편집  (0) 2009.12.03
Java XML Parser JDOM  (2) 2009.09.03
Posted by devop
TAG imap, javamail

댓글을 달아 주세요

1. POP
POP(Post Office Protocol)은 가장 널리 알려진 메일 프로토콜로서 오프라인 상태에서 메일 처리에 적합하도록 설계되어 있다. 오프라인 패러다임에서 메일은 서버에 저장되며, 개인 컴퓨터 사용자는 서버에 연결하여 사용자에서 배달된 메일을 자신의 컴퓨터로 다운로드 하기위해 주기적으로 클라이언트 프로그램을 가동한다. 따라서 모든 메일 처리는 클라이언트 컴퓨터 주위에서 이루어지게 되며 서버에 걸리는 오버헤드는 상대적으로 작아지게 되는데, 이는 많은 웹서비스 업체에서 손쉽게 메일 서비스를 제공할수 있는 이유이기도 하다.
하지만 POP에서는 의사 온라인 모드(클라이언트 프로그램이 서버에 메일을 남겨 놓는다고 볼때)에서 메일 클라이언트 프로그램이 편지함(메일이 저장되는 폴더)이나 상태 플래그(읽은 메일인지 아닌지와 같은) 와 같은 메세지 상태 정보를 접근/갱신하는것이 불가능하다. 이는 전적으로 클라이언트에서 이루어져야할 작업이며, 서버는 이런것을 신경쓰지 않는다.


2. IMAP
IMAP(Internet Message Access Protocol)은 오프라인 작업도 잘 처리할 수 있지만 온라인이나 disconnected동작에 강하다. 온라인 상태에서, 메일은 POP과 마찬가지고 서버로 전송되지만 클라이언트는 서버에서 어떠한 메일도 가져오지 않으며 지우지도 않는다. 여기서 클라이언트는 서버에게 헤더, 특정한 메세지의 내용, 또는 어떤 범주에 들어가는 메세지를 찾기 위한 요청을 할 수 있다.(예를 들면, 읽지 않은 메일을 가져오는것과 같은) 서버측 편지함의 메세지는 다양한 상태 플래그에 의해 표시될 수 있으며 사용자로부터 확실한 제거요청이 있기 전까지는 서버측 편지함에 계속 저장된다. 
따라서 아이폰이나 안드로이드 같은 모바일 플랫폼에서는 아무래도 POP보다는 상대적으로 클라이언트 부담이 적은 IMAP이 보다 원할한 서비스를 제공할 수 있다.
하지만 IMAP은 POP보다 복잡하고 서버에 부담을 많이 주는 프로토콜이기 때문에 POP처럼 많은 업체에서 손쉽게 제공해 줄수 있는 서비스가 아니다. 그래서 인지 IMAP을 지원하는 메일 서비스를 제공하는 업체가 그리 많지 않은게 현실이다.(구글, 다음, 네이버)


3. POP와 IMAP의 공통된 특성

  • 모두 오프라인 동작을 지원한다.
  • 메일은 서버에(항상 동작중인)에 저장된다.
  • 다양한 종류의 클라이언트 환경에서 새로운 메일을 접근할 수 있다.
  • 네트웍 상의 어느 곳에서도 접근 가능하다.
  • 프로토콜 사용이 자유롭다.
  • 자유롭게 구현할 수 있으며, 자유롭게 사용할 수 있다.
  • 클라이언트는 PC, MAC, UNIX 모두 가능하다.
  • 상업적인 구현도 가능하다.
  • SMTP 메일 게이트웨이가 필요없다.
  • 메일에 대한 접근만을 다룬다. (전송은 SMTP를 이용한다.)
  • Disconnected 작동을 위하여 지속적인 메세지 ID를 부여할 수 있다.

4. POP의 장점

  • 쉬운 프로토콜(구현이 쉽다)
  • IMAP에 비하여 클라이언트 소프트웨어가 많다.

5. IMAP의 장점

  • 지속적인 메세지 상태 플래그를 처리할 수 있다.
  • 메일 내용을 가져올 뿐만 나이라 저장할 수도 있다.
  • 여러 편지함을 관리하고 접근할 수 있다.
  • 메일외의 데이터에도 접합하다.
  • 접속시간과 디스크 사용량을 줄이기 위해 오프라인 패러다임을 사용할 수 있다.
  • 사용자 설정 관리(IMSP)를 위한 기반 프로토콜이 있다.
  • 온라인 성능을 최적하할 수 있다.

'프로그래밍 > 네트워크' 카테고리의 다른 글

MTU와 MSS  (0) 2010.03.29
IMAP과 POP의 비교  (0) 2010.01.27
Post Office Protocol(POP3)  (0) 2009.09.21
Active Object 패턴  (0) 2009.09.08
소켓 상태 전이  (2) 2009.07.29
Windows I/O 모델  (0) 2009.07.29
리틀엔디안(Little endian)과 빅엔디안(Big endian)  (0) 2009.07.29
Posted by devop
TAG imap, pop, 메일

댓글을 달아 주세요

POP는 Post Office Protocol의 줄임말로서 뒤의 숫자 3은 프로토콜의 버전을 의미합니다.

POP는 원격지에 있는 메일서버의 메일을 관리하기 위해서 만들어진 프로토콜로, 원격지의 서버에 접속해서 여러가지 명령을 통하여 메일 리스트를 확인하고, 확인된 메일을 로컬 컴퓨터로 복사한 후 가져온 메일은 삭제하는 방식을  사용합니다.(물론 가져온 메일을 삭제하지 않을수도 있습니다.)

한편, 메일 발송 등의 송신을 위해서는 SMTP라는 별도의 프로토콜을 이용해야 합니다.

POP와 비슷한 프로토콜로 IMAP이 있는데 IMAP보다는 POP이 보다 널리 사용되고 있습니다. IMAP은 POP에 비해 많은 기능을 제공하지만 프로토콜이 좀 더 복잡하고 메일을 POP과는 달리 로컬에서 관리하는게 아니라 원격지에서 관리를 합니다.


1. 동작방식

  • 메일클라이언트는 메일서버에 110번 포트로 TCP연결접속하면, 우선 사용자 이름 및 암호를 송신해야 합니다. 메일서버는 +OK 또는 -ERR 로 응답합니다.(인증단계)
  • 인증통과후 4개 명령(list retr, dele, quit)만으로 메일을 처리합니다.(트랜잭션 단계)
  • quit 명령 후 메일서버는 메세지 삭제 등을 시행합니다.(갱신단계)
  • 각 행의 마지막에는 행의 종료를 나타내는 CR/LF가 이어져야 합니다.


위 그림과 같이 POP3 서버 주소와 포트 110번을 이용해 TCP접속을 시도합니다.


위 그림과 같이 user 사용자명, pass 암호를 입력해 사용자 인증을 진행합니다.


stat는 메일서버의 상태를 확인하는 명령어로 위 그림에서는 총 1114개의 메일이 존재하며 약 380MB의 공간을 차지하고 있음을 알수 있습니다.


list 명령을 수행한 결과 화면 입니다. 첫번째 숫자는 메일의 ID를 나타내며, 두번째 숫자는 해당 메일의 크기를 의미합니다.


2. POP 명령어 형식 및 의미

  • user 사용자명 : 메일박스 사용자명
  • pass 암호 : 메일박스 암호
  • stat : 메일서버 상태
  • list [번호] : 메일 메세지들의 리스트
  • retr [번호 ] : 실제 메일의 취득
  • dele [번호] : 메일의 삭제
  • noop : 무조작
  • rset : 삭제 마크의 리셋
  • quit : 종료
  • top [번호, 행수]: 메세지 헤더의 표시
  • apop 메일박스명 : 메일박스, 인증문자열의 송신
  • uidl [번호] : 유니크한 ID 여부

'프로그래밍 > 네트워크' 카테고리의 다른 글

MTU와 MSS  (0) 2010.03.29
IMAP과 POP의 비교  (0) 2010.01.27
Post Office Protocol(POP3)  (0) 2009.09.21
Active Object 패턴  (0) 2009.09.08
소켓 상태 전이  (2) 2009.07.29
Windows I/O 모델  (0) 2009.07.29
리틀엔디안(Little endian)과 빅엔디안(Big endian)  (0) 2009.07.29
Posted by devop
TAG imap, POP3

댓글을 달아 주세요