メールの受信


.NetFrameworkではPop3サーバからメールを受信する方法は用意されていない。


なので、メールを受信したい場合はソケットを使ってPop3のコマンドを発行して
Pop3サーバにアクセスする必要がある。
ただし、ソケットを使って取得したものにはメールヘッダー等の本文以外のものも含まれているので
あまり使いやすいとは言えない。


以下、ソケットでのメールサーバアクセスの例(★の箇所は実行環境に合わせること)

'ライブラリのインポート
Imports System
Imports System.Text
Imports System.Net.Sockets

Public Class Form1

    'テスト用ドライバ
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Call getMail()

    End Sub

    ''' POP3よりメールを取得
    Private Sub getMail()
        Dim myMails() As String
        Dim msg As String = ""

        Dim stream As NetworkStream
        Dim client As New TcpClient

        'タイムアウトの設定
        client.ReceiveTimeout = 10000
        client.SendTimeout = 10000

        Try
            '★サーバーに接続(ホストとポートを指定)
            client.Connect("192.168.255.xxx", 110)

            'ストリームの取得
            stream = client.GetStream()
            '受信
            msg = ReceiveData(stream)

            '★USERの送信
            SendData(stream, "USER " + "hogeuser" + vbCrLf)
            '受信
            msg = ReceiveData(stream)

            '★PASSの送信
            SendData(stream, "PASS " + "hogepass" + vbCrLf)
            '受信
            msg = ReceiveData(stream)

            '■STATの送信
            SendData(stream, "STAT" + vbCrLf)
            '受信
            msg = ReceiveData(stream)

            'メール数の取得
            Dim myMailsCount As Integer = _
                Integer.Parse(msg.Split(" "c)(1))
            myMails = New String(myMailsCount - 1) {}

            'メールの件数分ループ
            Dim i As Integer
            For i = 1 To myMailsCount

                '■RETRの送信
                SendData(stream, "RETR " + i.ToString() + vbCrLf)

                '受信
                msg = ReceiveData(stream, True)

                myMails((i - 1)) = _
                    msg.Substring((msg.IndexOf(vbCrLf) + 2))

                MsgBox(msg)
            Next i

            '■QUITの送信
            SendData(stream, "QUIT" + vbCrLf)

            '受信
            msg = ReceiveData(stream)
        Catch
            MsgBox(Err.Description)
        Finally
            '切断
            client.Close()
        End Try

    End Sub

    'データを受信する(streamのReadを行う)
    Private Function ReceiveData( _
            ByVal stream As NetworkStream, _
            Optional ByVal multiLines As Boolean = False) As String

        Dim ibuffersize As Integer = 256
        Dim enc As Encoding = Encoding.GetEncoding(50220)

        Dim data(ibuffersize - 1) As Byte
        Dim len As Integer
        Dim msg As String = ""
        Dim iMemStream As New System.IO.MemoryStream

        Do
            '受信
            len = stream.Read(data, 0, data.Length)
            iMemStream.Write(data, 0, len)

            '文字列に変換する
            msg = enc.GetString(iMemStream.ToArray())

        Loop While stream.DataAvailable OrElse _
            ((Not multiLines OrElse msg.StartsWith("-ERR")) AndAlso _
                Not msg.EndsWith(vbCrLf)) OrElse _
            (multiLines AndAlso Not msg.EndsWith(vbCrLf + "." + vbCrLf))

        iMemStream.Close()

        Return msg
    End Function

    'データを送信する(streamへのWriteを行う)
    Private Sub SendData( _
            ByVal stream As NetworkStream, _
            ByVal msg As String)

        'byte型配列に変換
        Dim bData As Byte() = Encoding.ASCII.GetBytes(msg)

        '送信
        stream.Write(bData, 0, bData.Length)

    End Sub

End Class

動作確認環境:Windows XP sp2 ,Visual Stadio 2005