SMTP on C# (2)

この記事は古いです。ここも参照してください


emlファイルを送ることだけに特化してみました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace SMTP
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine("SMTP.exe from recipient eml");
                return;
            }
            
            SMTP smtp = new SMTP("localhost");
            
            smtp.From(args[0]);
            smtp.Recipient(args[1]);
            smtp.Send(args[2]);
            smtp.Quit();

            Console.ReadKey(true);
        }

        static string ToBase64(byte[] bytes)
        {
            return Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
        }
        static string ToBase64(string @string)
        {
            return Convert.ToBase64String(
                jisEnc.GetBytes(
                    @string
                ),Base64FormattingOptions.InsertLineBreaks
            );
        }
        static Encoding jisEnc = Encoding.GetEncoding(50220);
        static string ToBase64jis(string @string)
        {
            byte[] bytes = jisEnc.GetBytes(@string);

            return "=?ISO-2022-JP?B?" + ToBase64(bytes) + "?=";
        }

        public class SMTP
        {
            NetworkStream Stream;
            TcpClient Client;
            int Port;
            string Server;
            StreamReader Reader;
            List<string> messages;

            public SMTP(string Server, int Port)
            {
                this.Server = Server;
                this.Port = Port;
                Connect();
            }

            public SMTP(string Server)
            {
                this.Server = Server;
                this.Port = 25;
                Connect();
            }

            void Connect()
            {
                Client = new TcpClient(Server, Port);
                Stream = Client.GetStream();
                Stream.ReadTimeout = 5;
                Reader = new StreamReader(Stream);

                ReadEx("220");
                WriteLine("EHLO ", Server);
                ReadEx("250");

            }

            ~SMTP()
            {
                try
                {
                    Quit();
                }
                catch { }
            }

            string ReadEx(params string[] codes)
            {
                string read;
                do
                {
                    read = Read();
                    bool error = false;
                    foreach (string code in codes)
                    {
                        if (error = read.StartsWith(code))
                            break;
                    }
                    if (!error)
                    {
                        throw new Exception(read);
                    }
                    Console.WriteLine(read);
                } while (read[3] == '-');

                //Console.WriteLine();

                return read;
            }

            string Read()
            {
                return Reader.ReadLine();
            }

            void Write(byte[] bytearray)
            {
                Stream.Write(bytearray, 0, bytearray.Length);
            }
            void Write(byte[] bytearray, int offset, int size)
            {
                Stream.Write(bytearray, offset, size);
            }
            void Write(string write)
            {
                byte[] bytearray = System.Text.Encoding.UTF8.GetBytes(write);
                Write(bytearray);
            }
            void WriteLine(string write)
            {
                Write(write);
                Stream.Write(new byte[] { 13, 10 }, 0, 2);
            }
            void Write(params string[] write_array)
            {
                foreach (string write in write_array)
                {
                    Write(write);
                }
            }
            void WriteLine(params string[] write_array)
            {
                foreach (string write in write_array)
                {
                    Write(write);
                }
                Stream.Write(new byte[] { 13, 10 }, 0, 2);
            }

            public void From(string from)
            {
                WriteLine("MAIL FROM:<", from, ">");
                ReadEx("250");
            }

            public void Recipient(string rcpt)
            {
                WriteLine("RCPT TO:<", rcpt, ">");
                ReadEx("250", "251");
            }
            public void Recipient(params string[] rcpts)
            {
                foreach (string rcpt in rcpts)
                {
                    Recipient(rcpt);
                }
            }

            public void Send(string emlfile)
            {
                WriteLine("DATA");
                ReadEx("250", "354");

                FileStream fs = new FileStream(emlfile, FileMode.Open);
                long length = fs.Length;
                byte[] data;
                if (length > int.MaxValue)
                {
                    throw new Exception("too large file");
                }
                else
                {
                    data = new byte[length];
                    fs.Read(data, 0, (int)length);
                    fs.Dispose();
                }
                Write(data);

                WriteLine("\r\n.");
                ReadEx("250");
            }


            public void Quit()
            {
                WriteLine("QUIT");
                ReadEx("221");

                Reader.Dispose();
                Stream.Dispose();
            }
        }
    }
}

ローカルでRadishというソフトを起動して、

  • SMTP.exe 送り主 あて先 emlファイル

とすることで、送りつけます。

emlファイルはOutlook Expressとかで名前をつけて保存でいけます。もしくはInternetExplorerで名前をつけて保存で、形式をmhtにして、拡張子をemlにする事によっても作れます。わかりにくく言うと、ヘッダー情報のことです。