上周有個信箱卡了一封問題信,每次收信都從頭來一次,後面的信都收不到~
剛好那個信箱的 WebMail 網頁發生問題,管理單位聯絡困難,所以只好自己處理。
本來用 telnet 連線砍信,不過一共 276 封信,用 DELE nnn 指令要下到死,砍了 2x 封信就受不了了,砍信速度還沒有廣告信速度進來的快,所以改用 VB.NET 寫個小程式,透過 POP3 port 來抓信件總數,一次全砍。
剛好在 tw.bbs.comp.language 有人問到 VB.NET 如何處理 POP3 連線,就想這個功能可以做成自己的 WebMail 系統。如附圖。(可以看到我的廣告信滿多的 ^_^)
此系統透過 POP3 連線,先用 LIST 取得信件總數及各信件的大小,再用 TOP nnn 0 取得信件檔頭,在反解編碼字串,取得寄件者、eMail、標題、寄件日期等,列在信件列表。預設每 20 筆一頁,可透過 url PageSize 來變更。在信件列表支援直接刪除信件。
讀信時,透過 RETR nnn 來取信,再由反解編碼字串解開整封信。目前尚未撰寫支援 MIME 功能,此外,由於我這頻寬有限,目前只允許 100 kb 以下信件使用此功能。
另外支援新郵件、回信、轉寄等功能。
有興趣試用的親朋好友可跟璉璉說,由於頻寬有限,此功能只提供給親朋好友使用,使用的時機主要是針對無 WebMail 的信件伺服器、刪信、或是 WebMail 系統發生問題,只能透過 POP3 讀信,由於並未將信件下載到我這,是直接讀 POP3 伺服器,所以網路流量一來一回,消耗滿大的,因此不對外開放。若是發生大量使用的情形時,有可能關閉此功能或是透過隨機註冊碼來過濾使用者,大概就是這樣。
對了,目前測試,有的信件伺服器反應有點慢,不知道是否再做 DNS 反查~
網頁版的還沒有做一次全砍信的功能,若測試的親友有需要,再跟子璉說,不然就要等我下次再碰上問題信時,我才會處理。
讚讚
本來只是試寫 POP3 協定當作消遣…
現在新計畫將用得上,有時想想,運氣真是恐怖阿~
讚讚
您好
我是詢問8bit MIME 編碼的字串處理問題的peter,方便告知字串的正確轉換方式嗎(不應任意改用字串處理函數串接)。謝謝。
讚讚
MSN Spaces 的寬度設計,不太適合貼程式碼,可能仍然要以討論區那裡做後續討論。
我在收信的時候,是這樣來處理:
Private m_NetworkStream As System.Net.Sockets.NetworkStream …
Private Function GetReturnBytes(Optional ByVal bMultiLine As Boolean = False) As Byte()
Dim allBytes, nBytes As Integer
Dim bExit As Boolean = False
Dim eDate As Date = DateTime.Now.AddMilliseconds(m_TimeOut)
Dim rtnBytes As Byte()
Dim nBuffer As Integer = m_TcpClient.ReceiveBufferSize
Dim tBytes(m_TcpClient.ReceiveBufferSize – 1) As Byte
allBytes = -1 ReDim rtnBytes(allBytes)
Do Try ‘ 試試看網路有沒有抓到資料,記住,所有資料不會一口氣全進來,所以要慢慢等。
nBytes = m_NetworkStream.Read(tBytes, 0, nBuffer)
Catch
nBytes = 0
End Try
If nBytes > 0 Then
allBytes += nBytes
ReDim Preserve rtnBytes(allBytes)
Array.Copy(tBytes, 0, rtnBytes, allBytes – nBytes + 1, nBytes) ‘ 陣列相加
End If
System.Threading.Thread.Sleep(0) ‘ 讓執行緒睡一下,來等新資料從網路進來,也把 CPU 資源放出來,ASP.NET 沒有 Application.DoEvents 可用,只能這樣放 CPU 出來。
If m_NetworkStream.DataAvailable Then
eDate = DateTime.Now.AddMilliseconds(m_TimeOut)
Else
If allBytes > 1 Then
If bMultiLine Then ‘ 多行處理
… (bExit = True)
Else
… (bExit = True)
End If
End If
End If
If DateTime.Now > eDate Then ‘ 逾時處理
bExit = True
End If
Loop Until bExit
Return rtnBytes
End Function
我自己原始碼沒有加註解,這邊加一點註解,若是還有問題再說吧。
轉換為字串時,我是用
BytesToString(arrBytes, modStrTools.enuStandardCodePages.SCP_big5) ‘ 上面傳回來的位元組陣列
完整程式碼已經上網,可在右邊的 .Net 原始碼中找到,分類在字串處理函式中。
讚讚
剛剛看了一下,直接瀏覽網誌不會看到右邊的連結清單,所以我把 BytesToString 函數位置轉貼如下:
http://tlcheng.no-ip.com/TLCheng/Net/NetList.aspx?Action=Function&Module=6&Function=55
讚讚
補兩篇後續討論的連結:
http://forums.microsoft.com/MSDN-CHT/ShowPost.aspx?PostID=564371&SiteID=14
http://forums.microsoft.com/MSDN-CHT/ShowPost.aspx?PostID=581580&SiteID=14
讚讚
我用的發訊程式碼:
Public Function Quit() As String
Return SingleCommand("QUIT")
End Function
Private Function SingleCommand(ByVal strCommand As String, Optional ByVal bMultiLine As Boolean = False) As String
Return BytesToString(SingleCommandBytes(strCommand, bMultiLine), modStrTools.enuStandardCodePages.SCP_big5)
End Function
Private Function SingleCommandBytes(ByVal strCommand As String, Optional ByVal bMultiLine As Boolean = False) As Byte()
Dim sendBytes As Byte() = StringToBytes(strCommand & vbNewLine, modStrTools.enuStandardCodePages.SCP_CP_ASCII)
m_NetworkStream.Write(sendBytes, 0, sendBytes.Length)
Return GetReturnBytes(bMultiLine)
End Function
讚讚
http://forums.microsoft.com/MSDN-CHT/ShowPost.aspx?PostID=893718&SiteID=14
我在這篇有回到登入帳戶、密碼的原始碼可參考。
讚讚
由於新計畫中需要使用到附件功能,所以 MIME 部份已經加在 Windows 程式上。
網頁上現在還沒決定要不要加進去。
讚讚
在這篇回覆中,有說到取得 eml 檔及用 IE6/7 開啟 mht 格式的信件:
http://forums.microsoft.com/TechNet-CHT/ShowPost.aspx?PostID=1054166&SiteID=23&mode=1
讚讚
剛剛看到有人蒐尋 VB2005 POP3 SSL 來到這個位置,不過我在這個位置並沒有提到這件事,所以在這邊做簡單的補充:
當 POP3 通訊為加密的時候,請使用 .Net 內建 SslStream 取代 NetworkStream 取代,若要寫成通用型,可以這樣改,下面程式碼實測過可以用在 gMail 的連接上:
Private m_Stream As System.IO.Stream
…
Public Function ConnectMailServer(ByVal strMailServer As String, Optional ByVal nPort As Integer = 110, Optional ByVal bSSL As Boolean = False) As String
mailServer = strMailServer
mailPort = nPort
Try
m_TcpClient.Connect(mailServer, mailPort)
Catch
Return ""
End Try
If bSSL Then
m_Stream = New System.Net.Security.SslStream(m_TcpClient.GetStream(), False)
CType(m_Stream, System.Net.Security.SslStream).AuthenticateAsClient(strMailServer)
Else
m_Stream = m_TcpClient.GetStream()
End If
Return BytesToString(GetReturnBytes(), modStrTools.enuStandardCodePages.SCP_CP_ASCII)
End Function
讚讚
Hi,
璉大,感謝您提供的相關資訊,有時間的時候我也來實做看看 ~
讚讚
大哥!可以開放原始碼給小弟學習嗎? 因為對VB.NET很有興趣!所以想要多學習一些~不知道大哥是否願意指導一下小弟!
讚讚
有問題請至 MSDN 論壇討論,原始碼可參與先前相關討論。
讚讚