通用網頁讀信系統


上周有個信箱卡了一封問題信,每次收信都從頭來一次,後面的信都收不到~
剛好那個信箱的 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 反查~

Categories: 更新與回報 | 14 則迴響

文章分頁導航

14 thoughts on “通用網頁讀信系統

  1. 子璉

    網頁版的還沒有做一次全砍信的功能,若測試的親友有需要,再跟子璉說,不然就要等我下次再碰上問題信時,我才會處理。

  2. 子璉

    本來只是試寫 POP3 協定當作消遣…
    現在新計畫將用得上,有時想想,運氣真是恐怖阿~

  3. peter

    您好
    我是詢問8bit MIME 編碼的字串處理問題的peter,方便告知字串的正確轉換方式嗎(不應任意改用字串處理函數串接)。謝謝。

  4. 子璉

    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 原始碼中找到,分類在字串處理函式中。
     

  5. 子璉

    剛剛看了一下,直接瀏覽網誌不會看到右邊的連結清單,所以我把 BytesToString 函數位置轉貼如下:
    http://tlcheng.no-ip.com/TLCheng/Net/NetList.aspx?Action=Function&Module=6&Function=55

  6. 子璉

    我用的發訊程式碼:
    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

  7. 子璉

    http://forums.microsoft.com/MSDN-CHT/ShowPost.aspx?PostID=893718&SiteID=14
    我在這篇有回到登入帳戶、密碼的原始碼可參考。

  8. 子璉

    由於新計畫中需要使用到附件功能,所以 MIME 部份已經加在 Windows 程式上。
    網頁上現在還沒決定要不要加進去。

  9. 子璉

    在這篇回覆中,有說到取得 eml 檔及用 IE6/7 開啟 mht 格式的信件:
    http://forums.microsoft.com/TechNet-CHT/ShowPost.aspx?PostID=1054166&SiteID=23&mode=1

  10. 子璉

    剛剛看到有人蒐尋 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

  11. Bauann

    Hi,
    璉大,感謝您提供的相關資訊,有時間的時候我也來實做看看 ~

  12. 昶丞

    大哥!可以開放原始碼給小弟學習嗎? 因為對VB.NET很有興趣!所以想要多學習一些~不知道大哥是否願意指導一下小弟!

  13. 子璉

    有問題請至 MSDN 論壇討論,原始碼可參與先前相關討論。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

在 WordPress.com 建立免費網站或網誌.

%d 位部落客按了讚: