2006年7月31日星期一

在Microsoft DotNET上進行NNTP Protocol 開發心得

自幾年前,使用VB6開始一直都有寫過下NNTP Newsgroup Access既o野,一直都未有完成品,因為原因實在太多,效能,亂碼,Bug,等等問題都影響到我進展.上左DotNet後,使過很多NNTP既Library,如Smilla .NET Communication Library,雖然沒有亂碼問題,但效能上實在太差.其次那些較出名的IP*Work , Indy Socket等等,雖然效能可接受,但由於始終都是別人出品,要深層次去控制NNTP Protocol 是很難的. 近日的起心干再次研究....得到台灣Microsoft MVP的幫助,有了進展.

在DotNET上,要寫和Server交流的,都是要使用System.Net.Socket低下的Member.
其中TCPCleint是必須的. 除了要對Socket有了解,亦需要了解System.Text.Encoding的使用方法. 因為和外國不同的是,我們是中文字,需要進行轉碼(下文有解說) ,而外國都是英文,故普遍不用轉行轉碼. 而且當然要了解一下RFC977
這份文件.因為從RFC977,我們可以知道NNTP的Command,Response,以及State Code等等有用資料.因為在網上,即使你用Google Search,要找到DotNET上的NNTP資源實在少得可憐.
故以下是我個人小小心得,希望幫到有需要的人,當然有錯請更正^^

1. NNTP Server 接收的資料都是Bytes,而不是String.
當我們由NNTP Server接收到資料時,其實都是以ASCII編碼的Bytes形態.要顯示的話,需要使用ASCIIEncoding.GetBytes方式去取得
Bytes,並轉至DotNET預設的Unicode 和String.如果不轉的話,就是出現"????" 的問號出現了.

2. 傳送資料給NNTP Server其實也是Bytes
一般我們都會使用TCPClient下的GetStream以Read和Write方法去讀寫,就如第一個Point,在GetStream.Write時,都需要把NNTP Command進行String to Bytes的處理才送出.而部份人會使用System.IO下的StreamWriter去送出資料,可能會問,為什麼StreamWriter不用轉Bytes,其實因為StreamWriter在你送出前,已經自動轉成Bytes,所以至可以直接傳送.

3.什麼是MIME ? 什麼是8Bit Encoding ,什麼是Base64 ?
NNTP文章都一定有Mail Header,而Mail Header中都有MIME資訊, MIME含有Subject , Content-Type 和Content-Transfer-Encoding,例如:
Subject: Word =?Big5?B?VkJBpc5XZWJCcm93c2VysN3DRA==?=
Content-Type: text/plain; charset=Big5
Content-Transfer-Encoding: 8bit
Subject不用多說,是標題
Content-Type是信件型式和編碼
Content-Transfer-Encoding則是傳送編碼
明顯地我們看到Subject是未能正確顯示的,就是因為使用8Bit Encoding關係.
8Bit Encode顯示格式為:
=?encode?c?string?=
=? ?= 為起始和結束
encode 為語系編碼
c 為字串編碼方式,b 為 base64 、q 為 Quoted-printable Code.
"VkJBpc5XZWJCcm93c2VysN3DRA"
就是Base64的方式顯示了。
要轉回正常字串,先依字串編碼轉為ByteArray,再使用 .Net 的 Convert.FromBase64String 依語系轉回來即可。

4.如何處回覆的郵件至原文?
若以 Re: 起始的回覆郵件,都會有References的項目 ,一般顯示為 : <a href="mailto:44cc1cd0$1@news.3home.net">44cc1cd0$1@news.3home.net</a> , 冒號後的,就是原文Message-ID,在NNTP Server中的唯一的.故自然可以依據References去連結原文.

沒有留言:

發佈留言