상세 컨텐츠

본문 제목

Transport Events Sink 를 이용한 SMTP 서비스의 효율적 사용 2

General

by 탑~! 2010. 5. 14. 13:19

본문

Transport Events Sink 를 이용한 SMTP 서비스의 효율적 사용 2

5. 그럼 이제 본격적으로 분석해 보자
주석의 형태로 설명하며, 주석은 전부 녹색으로 처리한다.
그렇다고, 메일에 주석이라는 것이 존재하는 것은 결코 아니다.
앞으로 나올 강좌의 메일 내용을 보고 싶으면, 그냥 복사해서 주석을 제거한 다음 notepad에 붙여 .eml로 저장한후
outlook으로 열어보면 된다.
Received: from speed (SPEED25 [210.102.9.155]) by chaosdb.chaostrade with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2448.0)
id HLLR7HZX; Wed, 28 Mar 2001 01:58:44 +0900Message-ID: <004701c0b6e0$ff27c5a0$9b0966d2@elim.net>
'메시지와 메시지 객체를 구별하는 고유값이다.
From: =?ks_c_5601-1987?B?waTB+L/s? = <cnu97@hanmail.net>
'BASE64로 인코딩 되어있다. 전에 강좌에서 NewMail객체를 이용하여 메일주소가 아닌 '예명으로 메일을 보낼수 있다고 그랬는데, 여러분의 주소로 메일을 보낸후
'From이하의 ?--?를 복사해서 Newmail객체의 To에 붙이고서 메일을 발송해보면 '그럼 예명이 들어갈 것이다.

To: <cnu97@hanmail.net>Subject: test
Date: Wed, 28 Mar 2001 02:11:43 +0900MIME-Version: 1.0
'MIME버전이다.
Content-Type: multipart/mixed;boundary="----=_NextPart_000_0042_01C0B72C.6EEDDBE0"

'앞의 일반적인 데이터 형을 보니 복합part를 가지고 있다. 각각의 part를 bodypart라고 한다.
'그리고 뒤의 세부내용을 보니 mixed다. 뭔가 여러가지가 짬봉이 되어있다는 생각이 드는가?
'이제 boundary영역을 보면 뭐 복잡하게 되어있는데 이 부분의 part를 참조하라는 말이다.

X-Priority: 3

'메시지의 우선순위이다.
'이개념에 대해서 잠깐 생각하면, 외국넘들은 별로 원칙적이도 않은것 같은데
'나름대로는 꽤 원칙적이라고 떠든다.(어떻게 보면 융통성이 없다.)
'FAX나 MAIL이 오면 아무리 시급하더라도, 비서가 이것을 프린트해서 대장한테 가져다
'줄때는 언제나 날라온 순서대로 준다.(물론 이렇지는 않겠지만, 고객주문의 경우를 생각하면..)
'아무리 본문에 넘급함, 넘급함 외치고 외쳐도, 소리없는 아우성이다.
'절대 먼저 처리해주지 않는다. 먼저온것부터 처리, 그러다가 퇴근시간이 되면 칼같이
'집에 간다. 그래서 생긴것이 우선순위이다. 메시지에 급합, 나중뭐 이런것이 붙어있으면
'먼저온것 위에 살포시 포개준다. 완전히 이 헤더는 외국넘들의 습관에 따른 것이다.
'자랑스러운 한국인을 보라. 대충 메일 내용읽고, 나름대로의 중요도를 판단해버리지 않는가?
'무지 영리한 민족이다.

X-MSMail-Priority: Normal

'위에선 쓴 X-Priority와 하는 일이 같다.
'outlook이 X-Priority를 좀더 쉽게 읽을려고, 나름대로 변형해서 붙여버렸다.

X-Mailer: Microsoft Outlook Express 5.50.4522.1200
'MUA 버전이다.
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200
'OutLook Mime해석기의 버전이다.
This is a multi-part message in MIME format.
'여기서부터 본문시작이다. 단지 ASCII text에 불과하다.
------=_NextPart_000_0042_01C0B72C.6EEDDBE0
Content-Type: multipart/related;
type="multipart/alternative";
boundary="----=_NextPart_001_0043_01C0B72C.6EEDDBE0"

'가장 먼저 나왔던 boundary를 따라가 보니 이것이 나왔고, 이것은 다음으로 참조할
'bodypart를 알려준다. 역시 multipart이다.

------=_NextPart_001_0043_01C0B72C.6EEDDBE0
Content-Type: multipart/alternative;
boundary="----=_NextPart_002_0044_01C0B72C.6EEDDBE0"
'위에서 언급한 boundary를 따라가 보니 다른 part를 참조하라구 한다.
------=_NextPart_002_0044_01C0B72C.6EEDDBE0
Content-Type: text/plain;
charset="ks_c_5601-1987"
Content-Transfer-Encoding: base64

vsiz58fPvLy/5C4gDQpDRE8yLk/A1LTPtNkuDQogDQrAzLnMwfYgx8+zqiDDt7rOx9/AvQ0K
'content-type은 text/plain이구 charset="ks_c_5601-7987" 이구
'만약 charset이 생략되면 US-ASCII로 지정된다. 이 값이 default값이다.
'울 나라가 좀만 더 발전되면 기본값이 ks_c.... 이 값이 될 것이다.
'MUA가 인코딩한 방식은 base64라고 되어있다.
'위에 무슨 암호와 같은 것은 "안녕하세요.CDO2.0입니다."이 문자열을 인코딩한 것이다.

------=_NextPart_002_0044_01C0B72C.6EEDDBE0
Content-Type: text/html;charset="ks_c_5601-1987"
Content-Transfer-Encoding: base64
PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv
L0VOIj4NCjxIVE1MPjxIRUFEPg0KDQo8TUVUQSBjb250ZW50PSJNU0hUTUwgNS41MC40NTIyLjE4
MDAiIG5hbWU9R0VORVJBVE9SPg0KPFNUWUxFPjwvU1RZTEU+DQo8L0hFQUQ+DQo8Qk9EWSBiZ0Nv
bG9yPSNmZmZmZmY+DQo8RElWPjxGT05UIHNpemU9Mj6+yLPnx8+8vL/kLiA8L0ZPTlQ+PC9ESVY+
DQo8RElWPjxGT05UIHNpemU9Mj5DRE8yLk/A1LTPtNkuPC9GT05UPjwvRElWPg0KPERJVj48SU1H
IGFsdD0iIiBoc3BhY2U9MCBzcmM9ImNpZDowMDQxMDFjMGI2ZTAkZmYwNjMzZTAkOWIwOTY2ZDJA
ZWxpbS5uZXQiIA0KYWxpZ249YmFzZWxpbmUgYm9yZGVyPTA+PC9ESVY+DQo8RElWPjxGT05UIHNp
emU9Mj7AzLnMwfYgx8+zqiDDt7rOx9/AvTwvRk9OVD48L0RJVj48L0JPRFk+PC9IVE1MPg0K

'이것은 text/html이구 역시 내용은 "안녕하세요.CDO2.0입니다." 를 html로 바꾸어놓은
'것이다. 이시점에서 보건데, alternative라는 것은 양자택일이다.
'boundary값도 같다. 즉 MUA가 머리가 영리해서, html을 표시할 수 있으면 이것을
'이용하고 그렇지 않으면, 그냥 텍스트를 사용하라는 것이다.
'Content-Type:multipart/alternative;->의 의미는 바로 이것이다.
'만약 메일리더가 html을 모르는 녀석일때, text에 html을 지원하지 않습니다. 라는
'말을 덧붙이고 싶으면, 위의 text/plain의 부분에 이 말을 써주면 된다.
'outlook은 메시지의 본문을 보고 동일하게 이 2개의 값을 만들어낸다.
'물론 cdo2.0을 사용하면 그냥 모든것을 핸들링 할 수 있다.

------=_NextPart_002_0044_01C0B72C.6EEDDBE0--

'뒤에 "--"가 붙어있는 것으로 봐서 이 part의 끝이다.
'아래에서 두번째 part가 시작된다.

------=_NextPart_001_0043_01C0B72C.6EEDDBE0
Content-Type: image/gif;name="face.gif"
Content-Transfer-Encoding: base64
Content-ID: <004101c0b6e0$ff0633e0$9b0966d2@elim.net>
'gif파일이구, 이름은 face.gif이다. 본문에 텍스트가 아닌 그림등이 삽입
'될 때에는 name value가 들어간다. 당연 outlook으로 그림 못그리니깐
'삽입이라는 것도 파일첨부하고 같다. 다만 content-type만 다르다.
'드디어 Content-ID가 나왔다. 각각의 bodypart를 구별하기 위한 고유값이라고
'언급했다. 메시지ID는 각 메시지간에 구별을 위한 고유값이다.

R0lGODlhLAAsANU/AP39+vrLIfnKHOzs7P3SK9rY0vbSTfzup/K8Cv7siayNGP/qItXMrNXTyvbF
G/3XHm9YE/f28xULA/XCFf3XOf3lc+nObMCjGfrLFv3hIPrGC/jFFcO9q//63pJ2FdTFj9vFd/71
xv3gV/fIHPvOJenJHvjHGPTflNHOxN/e2/XMNUczCufEPOrXIePctvLDH+Pi4em7IPjJIOHCHdjB
HdW0HP3PDcnFuIBxUOPHW/Ds1ODATu7cOfLFKPfHH////yH5BAEAAD8ALAAAAAAsACwAQAb/wJ9w
SBwCOp1DRURpVg6hDqBIrQoBoqgI0yQJBCSCOEAKmAMC9PeLMQUmL920GKoAKhneSlJ6yNBnMmmC
f2aFDg8ZEBI0DxMbGxgfBSkDPwAGAWIEJGUyMg8LLQqLEqamKx4KJRkBPiMjJiYOGyYjGyocDZQw
RAAWCDKwDn+fsjIODrfJjyaQzggvTxwoKLspMBFWRgADMCkFBQ3j5OW74SnY2QBz25d1IT91NisQ
C5xlJBkrKw9eXwgQxHP3I8kPBhIgUHiwiUAgTmnMlDEDRsCtBR5M1XjgYp2QBBRAhpGx4IKpCwse
vBLwaYQDH69C0djDKIODNpAi5bhm6ccB/wSdZHQK8KcTy0MOBNiS9QWWs1obJlRwccMapZ5UBrjY
EXBCMh8TJrj0GhYOAgwsPlStdg3GgHbbAIRIIEKEARUMxfgjUSMGhoAqDsAlOGTupQo2SDSJocBf
0QAjHvgZkQbDlwkITgwuYtCFBxYUBBCgwAmfxIlfhhKyCMHDAwwu3voS7KJUjQxChQI6E/ELUaFN
M2RssQBwg0pTDojoYEB0iz0KFhClyNLQJ0MOMpRYZA/DBFkONOzEFiHEAyYT/5Tcs+JCogzwMzyY
oYAmBFaUTWDIOUEAiLbyYKBJeoAI1cl78EmGAS1QbRALJAJEJQIDVmFTGAIjGOIDRZ/I8P/KCMgQ
45QzziSFmQoJMFBVW5tFAIxXyvigDDIezlKLLJCE9QIFJ1DDFi/auNMNOAyAsEMMMYQVzQsssACC
WtVYcw42shHmCzsReJPOllzC4OUAAwRpZRVyVbCQDRh0gqYGNtiggQgHRLDZmEJ0kEACUhyAgz1l
+JMIPxl4oQECBoQwZ1xzsZMAATYoskJKEgmQwQUbWbYGZppZ2cFym2IwGgEYSOYJGkOlsYalESIg
WFwHHPBDAjaM5kUYDeUjCEVGfRFJIuJVOZsUOEgAWq0S8eZJIakJEOoiHmRgAHJEhBBCBMEq5BAZ
u0UkSETUoRFZCQl54IENFpBXZwIAJFD/kgQeLDCRJ2Nwi2sZET5AQ0ILWFYLA+Yq0QEFJCygQEKB
FqLGb4MQlYYPiTC7gCyzmAACL+lmATABopzkbiEdelgILBk8J8EKLTzgoH7h7XTVASSIsIkg67Kb
oADKJBNAIg9kpNECteznzAQY/MdLB2IALNEf2ulczwVMk3JKe5LZQstTkJDwAYAJaCBGUIX4IEAo
812gwNgxSCafA7K8gmMtDhBgwQ0AYiKawdwee91XTjkIoo0uIYAiNTxdYcAGE1lniCEuob0B2haR
CMkImBlwgI9AGnECAq7Acp0JyIDY0gg+yNIMiSMg0MNUa/E0GAA5YBgLZUcNY8KHEJPoYgACMYiQ
AAepp+NrERGAkKQDXkUMeiwTvBJVVHC47WOFHsU1QAoMcBVQV0pibzqUbLX1u5DTg1MNAx+A8OQH
KkYpJTpUHhoXAFmmE8789FOy5Zfu08kO/GB66T+YEZCTlYIAADs=

------=_NextPart_001_0043_01C0B72C.6EEDDBE0--

'part끝
'part 다시시작

------=_NextPart_000_0042_01C0B72C.6EEDDBE0
Content-Type: image/gif;name="icn_gongoo.gif"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="icn_gongoo.gif"

'이 한줄의 추가로(Content-Disposition) 본문에 삽입되지 않고, 첨부파일 형태로 된다.
'Content-Disposition:attachment를 attachment를 inline으로 바꾸어 보라.
'Content-Dispositon의 value값은 attachnet, inline이다. 그외의 파일
'이름이라든가, 파일사이즈 등이 있는데, msdn을 참고하면된다. 이 강좌 마지막에
'참고라는 index가 있는데, 여기를 따라가서 msdn을 보면 잘나온다.
'이제 이 부분을 빼고(Content-Disposition:attachment를 삭제해 보라)
'한번 메일을 읽어보면, 거의 모든 것을 이해하게 될것이다.
'여기에서 하나 생각해 볼 문제는 아무리 프로그램 교환에 대한
'감시가 있더라도 이부분만을 notepad에 붙여서 메일로 전송하면
'받은 사람은 역시 이것을 가지고서, 쉽게 이진 파일을 복원할 있을 것이다.
'그러나 이런 방법으로 프로그램 교환이나 그런것을 하지 말기를 바란다.
'우리는 건전한 프로그래머 아닌가?
'다시말하면, 자료저장 방식을 메일처럼 text로 할 수도 있다는 말이다.
'이것을 응용하면 뭔가 할 수도 있을것 같은데...

R0lGODlhLgAoAMT/AHmGxTLLMmWYZYTTM43WQazhdbznkM3trNzyxeX20/7//XXUBorbK6roYbTq
dMTzjff88fD55fr99vv9+HmiFO//fv/wAP9lMnVqak5NTcDAwMvLy5iYmH19fVtbWwAAACH5BAEA
ABoALAAAAAAuACgAQAX/oCaOY0SeaKquqge8ryePnmBfuKzvcuZnmJNnwWg8jo5kY7lkOJ/PhXRK
BbJEHyNSyWxAv9Rq8PrpdD5ls3rNZqPfaNbBUIhIRpDE/crHWj5XOjAwHgGGhh4VihU8PGIrQ0VH
D0kOXV5fUWFTVn2eKT4noX1wWB0aaYBkahtmqid2KQcHJp+2JxMIBHVCOixvKx8Ww50tg4SIizuL
ih4Uz88eP2NCRFqUXEyZmptSxSmR15WX207d3tQt1pPjXeUM5999jfT1vhqjpGlt/P1ufGVQuRpR
CsUHDghVldnQ6tUtgQM9FbRF6+GtAwgQoEhgIIFFFQ5JRDgwwIDGj7+GosVBoSABgj0iXBBCoQPH
BQ+QiMkTcgxAoQA7bAhY1gzaM3w+0tHs+TMZs0RPo8lYkFQdA3v2uHXbSSIcu2xNyp1Dx8LrFkvu
xMZTSnPdWXJqt7KtJult2m1juZ74UBcbWm1xw+hNgcYuYLxUdAxGiSKfCMf64EieTFly5DKVM2sO
SdiVq81wEr5KJXGNQoicUa1M9aGhxVQRV6lJ/QkYYxQhAAA7e09KBy8Px5HhyFHgQLOCbe3RRXFh
Q4d1Iy5W6Phi4K+S/TEGWPnw5X2KNVMO+BjxERqhJ3Im7dkmjcmNWc/RYnoqko8eXQxLxru3b985
C/0eTrwmkpuHiieD6ayZpZDNWR7X2YwGTW4onU8qqRSScaVBAAA7
------=_NextPart_000_0042_01C0B72C.6EEDDBE0
Content-Type: text/plain;name="check.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="check.txt"

OK
'인코딩 방식이 :7bit로 되어있다.
------=_NextPart_000_0042_01C0B72C.6EEDDBE0--


6. 참고
(1) 다음은 RFC에 나와이는 MIME에 관한 번호이다.(졸라 많다.)
822, 934, 1000, 1036, 1039, 1049, 1314, 1341, 1486, 1494, 1495, 1521, 1522, 1601, 1602, 1652, 1730, 1738, 1847, 1866, 1867, 1892, 1894, 1896, 1911, 2000, 2015, 2017, 2026, 2045, 2046, 2047, 2048, 2049, 2068, 2076, 2077, 2110, 2111, 2112, 2122, 2183, 2184, 2220, 2231, 2234, 2298, 2301, 2311, 2318
(2) MIME헤더를 보다 깊게 보고 싶으면 MSDN Library에 MIME Headers라는 항목이 있는데, 여기를 살펴보면 된다. 참고적으로 MSDN Library를 찾아보는 연습은 대단히 중요하기에. 세세한 링크나 위치는 적지 않는다. 위치를 찾는데 어려움이 따르면, 아래의 이미지를 참조해서 찾아나가길 바란다. 그저 이것저것 눌러보면, 대강 라이브러리의 전체 내용이 보이고, 그럼 내공향상에 엄청 도움이 될 것이다.

(3) 위의 내용을 참고하여 MSDN을 뒤져서, Content-Type의 헤더 값을 그냥 바꾸어 보라. 그럼 메시지가 UA에서 어떤 형태로 보여지는지 살펴 볼 수 있다. 이정도 파악이 되면, 여러분은 이제 인간 outlook express라고 불린다. 즉 Content-dispositon: attachment 라고 되어 있는 것을 attachment대신 inline으로 바꾸어 보는 것과 같은 연습을 말한다. 한번 바꾸어 보라.
(4) 위의 헤더 값중, 디지털 서명과 관련한 헤더값이 몇가지 있는데, 디지털 서명과 관련된 테스트및 기타의 문제는 강좌 끝마칠 정도에 설명할까 한다.
(5) msdn 및 RFC에 나와있는 헤더값중 중요한 것은 강좌 곳곳에 설명하기로 한다.
(6) 이상의 것을 이해한다면, 이전버전의 cdoNTS의 NEWMAIL객체를 통해서도 나름대로의 조작을 통해서 웹페이지 첨부라든가 하는 것을 할 수 있을 것이다. 물론 약간의 사고가 필요하다. 이 역시 강좌 곳곳에 설명하기로 한다.
(7) 이번 강좌는 그냥 강좌를 읽어보는 수준이 되어서는 안된다. 자기자신에게 수통의 메일을 보내고 그 파일을 조작하고, 세심히 눈으로 내용을 읽어 가는 과정이 필요하다. 실질적으로 이 과정을 통하면, 다음 CDO 개체 모델이 눈에 들어오며, 개체 모델의 파악이 끝나면, 여러분은 CDO2.0을 가지고 아이다루듯이 자연스럽게 프로그래밍을 할 수 있다. 메일의 모든 헤더내용과, 모든 의미를 파악할 수 있다는 것-멋진 일이 아닌가!!!


7. 마치면서
MIME를 설명하기 위해, 모든 헤더값등을 적는다는 것은 강좌로서는 불가능하다는 생각이 들었습니다. 나름대로는 가장 중요한 개념을 압축하여 놓았다고 생각하지만... 기타의 것은 MSDN을 참고하시면 됩니다. 그냥 쉽게 읽을 수 있을 것 같군요.(?) 여기에서 8bit니 base64니 하는 알고리즘을 언급하지 않았습니다. 솔직히 저도 공부하지는 않아서 로직은 잘 모릅니다. 텍스트 파일은 인코딩로직이 그리 어렵지 않으나, 이진 파일은 힘이 듭니다.
다음다음 강좌에 ASP로 구현된 BASE64디코딩, 인코딩 함수를 첨부하겠습니다. 이 부분은 관심이 있으시면, 인터넷을 통해서 나름대로 공부했으면 합니다. 나름대로는 CDO2.0 개체모델을 이해하기 위해서는 이정도면 충분하다고 생각합니다.
몇가지 언급하지 않은 부분과 빼먹은 부분은 IBODYPart 개체모델(정확이는 com 인터페이스) 에 대해 이야기 할때 좀더 덧 붙일까 합니다. CDO를 이용하면, DB에 BASE64로 인코딩해서 패스워드를 집어넣고, 다시 인코딩 할 수 있습니다. 이것에 관한 메일이 몇통 있었는데, 개인적으로는 암호화도 아니고, 그런데 굳이 이런 것이 보안에 그리 효용이 있을까 하는 생각을 해봅니다. 차리리 다른 쪽에 좀더 신경을 쓰는 것이...
다음 강좌부터는 기본적인 개요는 이정도로 하기로 하고, 이제 CDO object 에 대해서 이야기 드리겠습니다. 그 때부터는 코드가 많이 나올것 같군요. vb를 좀 건드려 볼까요? (아직은 .......) 그럼 여러분 다음 강좌에서 뵙겠습니다.
언제나 처음처럼



출처 : http://gipsi.egloos.com/677963

관련글 더보기