■■■

2016年4月4日月曜日

メールサーバーPOP3からメールを受信する方法

Network programming in .NET: C# & Visual Basic …
メールサーバーPOP3からメールを受信する方法
VB.NET
Imports System
Imports System.Text
Imports System.Net.Sockets

Namespace Dobon.Samples.Mail
    Public Class Pop3Mail
        Public Shared Sub Main()
            Dim mails() As String
            mails = Receive("localhost", 110, "userid", "password", True)

            Console.ReadLine()
        End Sub

        Public Shared Function Receive( _
                ByVal hostName As String, _
                ByVal portNumber As Integer, _
                ByVal userId As String, _
                ByVal passWord As String, _
                ByVal deleteMails As Boolean) As String()
            Dim mails As String() = Nothing
            Dim msg As String = ""
            Dim stream As NetworkStream = Nothing

            Dim client As New TcpClient
            client.ReceiveTimeout = 10000
            client.SendTimeout = 10000

            Try
                client.Connect(hostName, portNumber)
                stream = client.GetStream()
                msg = ReceiveData(stream)

                SendData(stream, "USER " + userId + vbCrLf)
                msg = ReceiveData(stream)

                SendData(stream, "PASS " + passWord + vbCrLf)
                msg = ReceiveData(stream)

                SendData(stream, "STAT" + vbCrLf)
                msg = ReceiveData(stream)
                Dim mailsCount As Integer = Integer.Parse(msg.Split(" "c)(1))
                mails = New String(mailsCount - 1) {}
                Dim i As Integer
                For i = 1 To mailsCount
                    SendData(stream, "RETR " + i.ToString() + vbCrLf)
                    msg = ReceiveData(stream, True)
                    mails((i - 1)) = msg.Substring((msg.IndexOf(vbCrLf) + 2))

                    If deleteMails Then
                        SendData(stream, "DELE " + i.ToString() + vbCrLf)
                        msg = ReceiveData(stream)
                    End If
                Next i

                SendData(stream, "QUIT" + vbCrLf)
                msg = ReceiveData(stream)
            Catch
                Throw
            Finally
                If Not stream Is Nothing Then
                    stream.Close()
                End If
                client.Close()
            End Try

            Return mails
        End Function

        Private Overloads Shared Function ReceiveData( _
                ByVal stream As NetworkStream, _
                ByVal multiLines As Boolean, _
                ByVal bufferSize As Integer, _
                ByVal enc As Encoding) As String
            Dim data(bufferSize - 1) As Byte
            Dim len As Integer
            Dim msg As String = ""
            Dim ms As New System.IO.MemoryStream

            Do
                len = stream.Read(data, 0, data.Length)
                ms.Write(data, 0, len)
                msg = enc.GetString(ms.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))

            ms.Close()

            If msg.StartsWith("-ERR") Then
                Throw New ApplicationException("Received Error")
            End If
            Console.Write(("S: " + msg))

            Return msg
        End Function
        Private Overloads Shared Function ReceiveData( _
                ByVal stream As NetworkStream, _
                ByVal multiLines As Boolean, _
                ByVal bufferSize As Integer) As String
            Return ReceiveData(stream, multiLines, bufferSize, _
                Encoding.GetEncoding(50220))
        End Function
        Private Overloads Shared Function ReceiveData( _
                ByVal stream As NetworkStream, _
                ByVal multiLines As Boolean) As String
            Return ReceiveData(stream, multiLines, 256)
        End Function

        Private Overloads Shared Function ReceiveData( _
                ByVal stream As NetworkStream) As String
            Return ReceiveData(stream, False)
        End Function

        Private Overloads Shared Sub SendData( _
                ByVal stream As NetworkStream, _
                ByVal msg As String, _
                ByVal enc As Encoding)
            Dim data As Byte() = enc.GetBytes(msg)
            stream.Write(data, 0, data.Length)

            Console.Write(("C: " + msg))
        End Sub
        Private Overloads Shared Sub SendData( _
                ByVal stream As NetworkStream, _
                ByVal msg As String)
            SendData(stream, msg, Encoding.ASCII)
        End Sub
    End Class
End Namespace
Network programming in .NET: C# & Visual Basic …
C#

using System;
using System.Text;
using System.Net.Sockets;

namespace Dobon.Samples.Mail
{
    public class Pop3Mail
    {
        public static void Main()
        {
            string[] mails;
            mails = Receive("localhost", 110, "userid", "password", true);

            Console.ReadLine();
        }

        public static string[] Receive(string hostName, int portNumber,
            string userId, string passWord, bool deleteMails)
        {
            string[] mails;
            string msg = "";
            NetworkStream stream = null;

            TcpClient client = new TcpClient();
            client.ReceiveTimeout = 10000;
            client.SendTimeout = 10000;

            try
            {
                client.Connect(hostName, portNumber);
                stream = client.GetStream();
                msg = ReceiveData(stream);

                SendData(stream, "USER " + userId + "\r\n");
                msg = ReceiveData(stream);

                SendData(stream, "PASS " + passWord + "\r\n");
                msg = ReceiveData(stream);

                SendData(stream, "STAT\r\n");
                msg = ReceiveData(stream);
                int mailsCount = int.Parse(msg.Split(' ')[1]);
                mails = new string[mailsCount];

                for (int i = 1; i <= mailsCount; i++)
                {
                    SendData(stream, "RETR " + i.ToString() + "\r\n");
                    msg = ReceiveData(stream, true);
                    mails[i - 1] = msg.Substring(msg.IndexOf("\r\n") + 2);

                    if (deleteMails)
                    {
                        SendData(stream, "DELE " + i.ToString() + "\r\n");
                        msg = ReceiveData(stream);
                    }
                }
                SendData(stream, "QUIT\r\n");
                msg = ReceiveData(stream);
            }
            catch
            {
                throw;
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
                client.Close();
            }

            return mails;
        }

        private static string ReceiveData(NetworkStream stream,
            bool multiLines, int bufferSize, Encoding enc)
        {
            byte[] data = new byte[bufferSize];
            int len;
            string msg = "";
            System.IO.MemoryStream ms = new System.IO.MemoryStream();

            do
            {
                len = stream.Read(data, 0, data.Length);
                ms.Write(data, 0, len);
                msg = enc.GetString(ms.ToArray());
            }
            while (stream.DataAvailable ||
                ((!multiLines || msg.StartsWith("-ERR")) &&
                !msg.EndsWith("\r\n")) ||
                (multiLines && !msg.EndsWith("\r\n.\r\n")));

            ms.Close();

            if (msg.StartsWith("-ERR"))
            {
                throw new ApplicationException("Received Error");
            }

            Console.Write("S: " + msg);

            return msg;
        }
        private static string ReceiveData(NetworkStream stream,
            bool multiLines, int bufferSize)
        {
            return ReceiveData(stream, multiLines, bufferSize,
                Encoding.GetEncoding(50220));
        }
        private static string ReceiveData(NetworkStream stream,
            bool multiLines)
        {
            return ReceiveData(stream, multiLines, 256);
        }
        private static string ReceiveData(NetworkStream stream)
        {
            return ReceiveData(stream, false);
        }

        private static void SendData(NetworkStream stream,
            string msg, Encoding enc)
        {
            byte[] data = enc.GetBytes(msg);
            stream.Write(data, 0, data.Length);

            Console.Write("C: " + msg);
        }
        private static void SendData(NetworkStream stream,
            string msg)
        {
            SendData(stream, msg, Encoding.ASCII);
        }
    }
}
Network programming in .NET: C# & Visual Basic …
■■■