Montag, 20. März 2017

C# Video-Tutorial Teil 1 (Installation und Hallo Welt)

Ich habe mich entschieden, eine Video-Tutorial-Reihe über C# zu beginnen, in welcher ich das erste Video veröffentlicht habe.
Dafür gehen wir einen Schritt zurück und fangen ganz vorne an: Im ersten Video erkläre ich Grundlegendes über Programmiersprachen, zeige den Download und die Installation von Visual Studio und erstelle mit euch ein erstes "Hallo Welt" Programm.
Somit richtet sich speziell das erste Video an komplette Programmieranfänger - ich würde mich freuen, den ein oder anderen für Programmieren und die Sprache C# begeistern zu können.
Ich plane, in etwa jede Woche ein neues Video zu veröffentlichen - die Themen werden rasch voranschreiten, sodass etwas fortgeschrittenere Programmierer dann dazu steigen können.
Seid gnädig zu mir, dies ist mein erstes vertontes Video. Über Feedback o.ä. freue ich mich natürlich wie immer!

Montag, 6. März 2017

Simulated Annealing mit C#

Nachdem ich in einem vorigen Post genetische Algorithmen beschrieben habe, möchte ich in diesem Post ein anderes heuristisches, an der Natur orientiertes Optimierungsverfahren vorstellen: Simulated Annealing.
Vorbild ist das Abkühlen von Stoffen, bei welchem sich die Atome anfangs bei hoher Temperatur viel bewegen und größere Distanzen überwinden (am Anfang der Optimierung legen wir große Schritte im Suchraum zurück). Mit fortschreitender Zeit verringert sich die Bewegung der Atome, das System erreicht einen stabilen Zustand (gegen Ende der Suche suchen wir nur noch lokal nach Verbesserungen und enden in einem lokalen Minimum).
Dieses Verfahren wird zum Beispiel zum Planen von Verbindungswegen auf Computerchips eingesetzt.
Im Gegensatz zu genetischen Algorithmen arbeiten wir bei Simulated Annealing nicht mit einem Pool von Lösungen, sondern stets nur mit einer einzigen. Eine Schar an Lösungen bietet Vorteile bei der Auswahl, verlangsamt den Prozess jedoch natürlich auch. Die Erzeugung einer neuen Lösung lässt sich mit der asexuellen Fortpflanzung vergleichen: Basierend auf unserer aktuellen Lösung modifizieren wir diese um so zu einer neuen Lösung zu gelangen. Hierfür definieren wir uns einen Graph, welcher die Nachbarschaftsbeziehungen der Lösungen repräsentiert, und durchlaufen diesen.
Das wilde Herumspringen der Moleküle bei hoher Temperatur und das dadurch verbundene Durchsuchen eines großen Suchraums modellieren wir mit einer Akzeptanzwahrscheinlichkeit: Ist die neue gefundene Lösung besser als die aktuelle, übernehmen wir diese immer als neue aktuelle Lösung. Ist die gefundene Lösung jedoch schlechter, übernehmen wir diese nur mit einer Wahrscheinlichkeit von e-Δ/T.
Hierbei entspricht Δ der Differenz der Lösungswerte (Ergebnis neuer Lösung - Ergebnis aktuelle Lösung) und T der aktuellen Temperatur. Die Wahrscheinlichkeit, die neue Lösung zu akzeptieren, nimmt also mit der Temperatur ab, und mit der Höhe der Verschlechterung des Lösungswertes (setzt einfach mal ein paar Werte in die Formel ein).
In jedem Schritt des Algorithmus wird die Temperatur nach einem bestimmten Verfahren abgekühlt, wir nehmen hier das geometrische Abkühlungsschema TNeu = TAlt * α.
Als Pseudocode sieht der Algorithmus also wie folgt aus:
Aktuelle_Lösung = Zufällige Lösung
T = TStart
Solange T > TEnde:
   Temp = Zufällige Nachbarlösung von Aktuelle_Lösung
   Wenn Temp besser als Aktuelle_Lösung:
      Aktuelle_Lösung = Temp
   Sonst:
      Aktuelle_Lösung = Temp mit o.g. Wahrscheinlichkeit
   T = T * α. 

Wenden wir nun Simulated Annealing auf das TSP - Problem an, welches bereits im Post zu genetischen Algorithmen vorgestellt wurde. In unserem Nachbarschaftsgraph sind zwei Lösungen benachbart, wenn sie durch Tauschen zweier Städte in der Rundreise ineinander übergeführt werden können. Als Beispiel: Die Lösung ABC ist mit den Lösungen BAC, CAB und ACB benachbart.
Zu Beginn des Algorithmus erstellen wir in der Funktion Initialize() eine zufällige Initiallösung. Hierfür probieren wir solange aus, bis wir eine gültige Lösung gefunden haben, also eine, in welcher alle Städte miteinander verbunden sind. Dies ist nötig, da der Algorithmus allein durch das Tauschen zweier Städte nur sehr schlecht von einer schlechten Lösung mit Kosten unendlich wegfindet.
In der Funktion Go() befindet sich die Hauptschleife des Algorithmus. In jeder Iteration wird mit der Funktion CreateRandomNeighbor() eine zufällige neue Lösung aus der aktuellen heraus erzeugt. Dafür werden, wie gesagt, zwei zufällige Städte in der Rundtour getauscht.
Die Entscheidung, ob die neu erzeugte Lösung akzeptiert wird, wird nach oben beschriebenem Kriterium getroffen.
Als Starttemperatur wähle ich hier 1000, als Endtemperatur 0.01, für α 0.999999.
Mit diesen Parametern erreicht der Algorithmus bei 100 zufälligen Instanzen der Größe 20 im Durchschnitt einen Zielfunktionswert von 4516.
Ich werde demnächst einen eigenen Post zum Vergleich von genetischen Algorithmen und Simulated Annealing und zur Wahl der Parameter schreiben, im ersten Vergleich ist Simulated Annealing damit jedoch besser.
Dies bestätigt auch meine Meinung, ich persönlich ziehe das schlanke, einfache aber effektive Prinzip von Simulated Annealing vor, ebenfalls ist die Geschwindigkeit ein ausschlaggebendes Argument.
Auch ist bei genetischen Algorithmen nicht klar, ob das Prinzip der sexuellen Reproduktion bei mathematischen Problemen sinnvoll angewendet werden kann.

Zu guter Letzt der Code:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SA_TSP
{
    class Program
    {
        static void Main(string[] args)
        {
            TSPInstance Instance = CreateRandomTSPInstance(20);
            SimulatedAnnealing SA = new SimulatedAnnealing();
            SA.Go(Instance, true, 1000, 0.01, 0.999999);
        }

        // Create a random TSP instance, connect two cities with probability 70 % and choose a length between 0 and 1000.
        public static TSPInstance CreateRandomTSPInstance(int n)
        {
            TSPInstance Instance = new TSPInstance(n);
            Random Rnd = new Random();
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (Rnd.Next(100) < 70)
                    {
                        Instance.AddConnection(i, j, Rnd.Next(1000));
                    }
                }
            }
            return Instance;
        }

    
    }

    public class TSPInstance
    {
        public int n;
        public int[][] Connections;

        public TSPInstance(int _n)
        {
            n = _n;
            Connections = new int[n][];
            for (int i = 0; i < n; i++)
            {
                Connections[i] = new int[n];
                for (int j = 0; j < n; j++)
                {
                    Connections[i][j] = int.MaxValue;
                }
            }
        }

        public void AddConnection(int start, int end, int distance)
        {
            Connections[start][end] = distance;
        }
    }

    public class SimulatedAnnealing
    {
        public class Individual : ICloneable
        {
            public double Fitness;
            public int[] Tour;

            public Individual(int length)
            {
                Tour = new int[length];
            }

            // creates a deep copy of an individual
            public object Clone()
            {
                Individual Cloned = new Individual(Tour.Length);

                for (int i = 0; i < Tour.Length; i++)
                {
                    Cloned.Tour[i] = Tour[i];
                }
                Cloned.Fitness = Fitness;
                return Cloned;
            }
        }

        Individual CurrentSolution;
        TSPInstance Instance;

        public void Initialize()
        {
            // fill the initial population, for each individual create a random permutation of the cities

            Random Rnd = new Random();
            double Fitness = int.MaxValue;

            // create random permutations, as long as a valid tour is found
            while (Fitness == int.MaxValue)
            {
                List<int> Cities = new List<int>();
                for (int j = 0; j < Instance.n; j++)
                {
                    Cities.Add(j);
                }
                int Counter = 0;
                while (Cities.Count > 0)
                {
                    int Index = Rnd.Next(Cities.Count);
                    CurrentSolution.Tour[Counter++] = Cities[Index];
                    Cities.RemoveAt(Index);
                }
                CurrentSolution.Fitness = CalculateFitness(CurrentSolution);
                Fitness = CurrentSolution.Fitness;
            }
        }

        public Individual CreateRandomNeighbor()
        {
            // switch to random cities in the tour
            Random Rnd = new Random();
            Individual Cloned = (Individual)CurrentSolution.Clone();
            int End = Rnd.Next(Instance.n);
            int Start = Rnd.Next(Instance.n);
            int Temp = Cloned.Tour[Start];
            Cloned.Tour[Start] = Cloned.Tour[End];
            Cloned.Tour[End] = Temp;
            Cloned.Fitness = CalculateFitness(Cloned);
            return Cloned;
        }

        public Individual Go(TSPInstance inst, Boolean print, double tstart, double tend, double alpha)
        {
            Instance = inst;
            double T = tstart;
            CurrentSolution = new Individual(inst.n);

            Initialize();

            double LastPrint = tstart;

            // repeat as long as the temperature is over some threshold
            while (T > tend)
            {
                Individual NewSolution = CreateRandomNeighbor();
                if (NewSolution.Fitness < CurrentSolution.Fitness)
                    CurrentSolution = NewSolution;
                else
                {
                    double AcceptanceProbability = Math.Exp(-(NewSolution.Fitness - CurrentSolution.Fitness) / T);
                    Random Rnd = new Random();
                    if (Rnd.NextDouble() <= AcceptanceProbability)
                        CurrentSolution = NewSolution;
                }
                T = T * alpha;
                if (print && (LastPrint - T > 50))
                {
                    Console.WriteLine("Temperature: " + T.ToString());
                    Console.WriteLine("Current Solution: " + CurrentSolution.Fitness.ToString());
                    LastPrint = T;
                }
            }

            if (print)
                Console.WriteLine("Best: " + CurrentSolution.Fitness.ToString());

            return CurrentSolution;
        }

        public int CalculateFitness(Individual ind)
        {
            // sum over entire tour and return costs
            int Costs = 0;
            for (int i = 0; i < ind.Tour.Length; i++)
            {
                if (i == ind.Tour.Length - 1)
                {
                    if (Instance.Connections[ind.Tour[i]][ind.Tour[0]] == int.MaxValue)
                        return int.MaxValue;
                    Costs += Instance.Connections[ind.Tour[i]][ind.Tour[0]];
                }
                else
                {
                    if (Instance.Connections[ind.Tour[i]][ind.Tour[i + 1]] == int.MaxValue)
                        return int.MaxValue;
                    Costs += Instance.Connections[ind.Tour[i]][ind.Tour[i + 1]];
                }
            }
            return Costs;
        }
    }
}

Donnerstag, 27. Oktober 2016

Emails senden und empfangen (POP3- und IMAP-Server, mit SSL-Verschlüsselung)

Vor langer Zeit habe ich beschrieben, wie man mit C# Emails senden und empfangen kann. Damals war dies noch ohne SSL-Verschlüsselung möglich, heutzutage ist diese jedoch bei den meisten Anbietern Pflicht. In diesem Post möchte ich daher zeigen, wie man Emails unter Benutzung einer SSL-Verschlüsselung sendet und empfängt. Das Grundprinzip bleibt dabei das gleiche wie in den vorigen Posts beschrieben - für die Grundlagen ist der Leser daher auf diese Posts verwiesen.
Als weiteren Punkt soll dieser Post erklären, wie Emails von einem IMAP Server gelesen werden können - im letzten Post wurde nur ein POP3 Server genutzt. Außerdem wird ein fertiger Email-Client in C# präsentiert und die benötigen Anmeldeinformationen für gängige Email-Anbieter.

Kurz zur Wiederholung der Grundlagen: Für das Senden von Emails können .Net Funktionen genutzt werden. Dafür wird die Klasse SmtpClient benutzt, welcher die Anmeldedaten des Email-Accounts übergeben werden, und die dann eine Email als Instanz der Klasse MailMessage losschickt.

Das Empfangen von Emails ist etwas mühseliger, hierzu müssen manuell Befehle an den Server geschickt und die Antworten verarbeitet werden. Dafür bietet sich die Benutzung diverser Bibliotheken an, welche die Funktionalität abstrahieren.
In diesem Post werde ich aber zeigen, wie die Kommunikation mit einem Email-Server im Detail aussieht, und jeden Aspekt selber implementieren.
Mittels einem TcpClient bauen wir die Verbindung zum Mail-Server auf, und initialisieren dann einen SslStream, mit welchem wir dem Server die Befehle schicken und dessen Antworten empfangen.
Dabei gibt es nun Unterschiede zwischen einem POP3- und einem IMAP-Server.
Mögliche Befehle für einen POP3- und IMAP-Server können hier und hier gefunden werden, außerdem habe ich die Befehle für einen POP3-Server in meinem vorigen Post beschrieben.
Hier setze ich deren Verständnis voraus (denke aber auch, dass sie relativ selbsterklärend sind). Kurz zum Nachrichtenformat: Ein POP3-Server beendet Anfragen zur Auflistung aller verfügbarer und bestimmter Emailnachrichten mit einem ".", daher lassen wir den Client solange vom Stream lesen, bis dieses Zeichen empfangen wurde. Schickt man einem IMAP-Server einen Befehlsnamen mit, antwortet dieser am Ende jeder Nachricht mit X OK - daher warten wir auf diese Zeile.

Unten stehend findet sich der komplette Code eines Email-Clients, mit welchem Emails gesendet und empfangen werden können.
Die benötigen Konteninformationen (d.h. Server, Port, Benutzername und Passwort) sind die gleichen, wie sie zum Beispiel in Outlook eingegeben werden müssen.
Hier eine Übersicht über gänge Email-Anbieter:

Empfangen:

Name: Gmail
Typ: IMAP
Server: imap.gmail.com
Port: 993
Benutzername: Komplette Emailadresse

Name: Gmx
Typ: POP3
Server: pop.gmx.net
Port: 995
Benutzername: Komplette Emailadresse

Name: Web
Typ: POP3
Server: pop3.web.de
Port: 995
Benutzername: Emailadresse bis zum @ (also bei xyz@web.de xyz)


Senden:

Name: Gmail
Server: smtp.gmail.com
Port: 587
Benutzername: Komplette Emailadresse

Name: Gmx
Server: mail.gmx.net
Port: 587
Benutzername: Komplette Emailadresse

Name: Web
Server: smtp.web.de
Port: 587
Benutzername: Emailadresse bis zum @ oder komplette Emailadresse

Der Code:

Form1.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net.Security;
using System.IO;
using System.Net.Mail;

namespace Emails
{


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        EmailReceiver MyReceiver = null;

        private void button1_Click(object sender, EventArgs e)
        {
            if (radioButton1.Checked)
            {
                MyReceiver = new POPReceiver();
            }
            if (radioButton2.Checked)
            {
                MyReceiver = new IMAPReceiver();
            }

            MyReceiver.Connect(textBox1.Text, Int32.Parse(textBox2.Text), textBox3.Text, textBox4.Text);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            textBox6.Text = MyReceiver.ListMails();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            textBox6.Text = MyReceiver.GetMail(Int32.Parse(textBox5.Text));
        }

        private void button5_Click(object sender, EventArgs e)
        {
            // Send an email
            // Setup mail client, input credentials ...
            SmtpClient MailClient = new SmtpClient(textBox10.Text, int.Parse(textBox9.Text));
            // Enable SSL
            MailClient.EnableSsl = true;
            System.Net.NetworkCredential Credentials = new System.Net.NetworkCredential(textBox8.Text, textBox7.Text);
            MailClient.Credentials = Credentials;

            // Define the email and send it
            MailMessage Email = new MailMessage();
            Email.From = new MailAddress(textBox8.Text);
            Email.To.Add(textBox11.Text);
            Email.Subject = textBox13.Text;
            Email.Body = textBox12.Text;

            MailClient.Send(Email);
        }

    }

    // Abstract class, from which the specific classes POPReceiver and IMAPReceiver are derived
    public abstract class EmailReceiver
    {
        // TCP client to connect to the server
        public TcpClient MailServer = null;
        // SSL stream for the secure connection
        public SslStream SslStream = null;
        // StreamListener to read from the stream
        public StreamReader StreamListener;
        // Byte buffer to encode the commands send to the server
        public byte[] CommandBuffer = new byte[1024];

        // Connect to the mail server
        public abstract bool Connect(string server, int port, string user, string password);

        // Close the connection
        public abstract void Quit();

        // List all emails
        public abstract string ListMails();

        // Get specified email
        public abstract string GetMail(int id);

        // Send a command to the server and return the response
        public abstract string ExecuteCommand(string command);
    }

    // To be used with a POP3 server
    public class POPReceiver : EmailReceiver
    {
        public override bool Connect(string server, int port, string user, string password)
        {
            // Connect to the server via TCP
            MailServer = new System.Net.Sockets.TcpClient(server, port);

            // Establish the SSL stream
            SslStream = new System.Net.Security.SslStream(MailServer.GetStream());
            SslStream.AuthenticateAsClient(server);

            StreamListener = new StreamReader(SslStream);

            if (MailServer.Connected)
            {
                // Send the login commands and show the results
                MessageBox.Show(StreamListener.ReadLine());

                CommandBuffer = Encoding.ASCII.GetBytes("USER " + user + "\r\n");
                SslStream.Write(CommandBuffer, 0, CommandBuffer.Length);
                MessageBox.Show(StreamListener.ReadLine());

                CommandBuffer = Encoding.ASCII.GetBytes("PASS " + password + "\r\n");
                SslStream.Write(CommandBuffer, 0, CommandBuffer.Length);
                MessageBox.Show(StreamListener.ReadLine());

                return true;
            }

            return false;
        }

        public override void Quit()
        {
            // Close the connection
            CommandBuffer = Encoding.ASCII.GetBytes("QUIT\r\n");
            SslStream.Write(CommandBuffer, 0, CommandBuffer.Length);
            MessageBox.Show(StreamListener.ReadLine());
        }

        public override string ListMails()
        {
            return ExecuteCommand("LIST\r\n");
        }

        public override string GetMail(int mailNr)
        {
            return ExecuteCommand("RETR " + mailNr + "\r\n");
        }

        public override string ExecuteCommand(string command)
        {
            // Send the specified command
            CommandBuffer = Encoding.ASCII.GetBytes(command);
            SslStream.Write(CommandBuffer, 0, CommandBuffer.Length);

            StringBuilder Res = new StringBuilder();

            // The POP3 commands LIST and RETR, for which this function is used, finished by outputting "."
            // as last line.
            // Thus read as long as this line is found.
            string TempLine = StreamListener.ReadLine();
            while (TempLine != ".")
            {
                Res.Append(TempLine + "\r\n");
                TempLine = StreamListener.ReadLine();
            }

            return Res.ToString();
        }
    }

    public class IMAPReceiver : EmailReceiver
    {
        static int Counter = 0;

        public override bool Connect(string server, int port, string user, string password)
        {
            // Connect to the server via TCP
            MailServer = new System.Net.Sockets.TcpClient(server, port);

            // establish the SSL stream
            SslStream = new System.Net.Security.SslStream(MailServer.GetStream());
            SslStream.AuthenticateAsClient(server);

            StreamListener = new StreamReader(SslStream);

            if (MailServer.Connected)
            {
                // Send command to login
                MessageBox.Show(ExecuteCommand("LOGIN " + user + " " + password + "  \r\n"));

                return true;
            }

            return false;
        }

        public override void Quit()
        {
            // Befehl zum Trennen senden
            CommandBuffer = Encoding.ASCII.GetBytes("QUIT\r\n");
            SslStream.Write(CommandBuffer, 0, CommandBuffer.Length);
            MessageBox.Show(StreamListener.ReadLine());
        }

        public override string ListMails()
        {
            return ExecuteCommand("SELECT INBOX\r\n");
        }

        public override string GetMail(int mailNr)
        {
            return ExecuteCommand("FETCH " + mailNr + " body[header]\r\n") + " " + ExecuteCommand("FETCH " + mailNr + " body[text]\r\n");
        }

        public override string ExecuteCommand(string command)
        {
            // Prefix command with unique line number
            command = "aa" + Counter.ToString() + " " + command;

            CommandBuffer = Encoding.ASCII.GetBytes(command);
            SslStream.Write(CommandBuffer, 0, CommandBuffer.Length);
            SslStream.Flush();

            StringBuilder Res = new StringBuilder();

            string TempLine = StreamListener.ReadLine();
            // An IMAP server specifies the end of its response with "line number OK", thus read until this is found.
            while (!TempLine.Contains("aa" + Counter.ToString() + " OK"))
            {
                Res.Append(TempLine + "\r\n");
                TempLine = StreamListener.ReadLine();
            }

            Counter++;

            return Res.ToString();
        }
    }
}

Form1.Designer.cs:

namespace Emails
{
    partial class Form1
    {
        /// <summary>
       /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
       /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
       /// Required method for Designer support - do not modify
       /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.tabControl1 = new System.Windows.Forms.TabControl();
            this.tabPage1 = new System.Windows.Forms.TabPage();
            this.textBox6 = new System.Windows.Forms.TextBox();
            this.textBox5 = new System.Windows.Forms.TextBox();
            this.button3 = new System.Windows.Forms.Button();
            this.radioButton2 = new System.Windows.Forms.RadioButton();
            this.radioButton1 = new System.Windows.Forms.RadioButton();
            this.button2 = new System.Windows.Forms.Button();
            this.button1 = new System.Windows.Forms.Button();
            this.textBox4 = new System.Windows.Forms.TextBox();
            this.label4 = new System.Windows.Forms.Label();
            this.textBox3 = new System.Windows.Forms.TextBox();
            this.label3 = new System.Windows.Forms.Label();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.tabPage2 = new System.Windows.Forms.TabPage();
            this.textBox13 = new System.Windows.Forms.TextBox();
            this.label11 = new System.Windows.Forms.Label();
            this.button5 = new System.Windows.Forms.Button();
            this.textBox12 = new System.Windows.Forms.TextBox();
            this.label10 = new System.Windows.Forms.Label();
            this.textBox11 = new System.Windows.Forms.TextBox();
            this.label9 = new System.Windows.Forms.Label();
            this.textBox7 = new System.Windows.Forms.TextBox();
            this.label5 = new System.Windows.Forms.Label();
            this.textBox8 = new System.Windows.Forms.TextBox();
            this.label6 = new System.Windows.Forms.Label();
            this.textBox9 = new System.Windows.Forms.TextBox();
            this.label7 = new System.Windows.Forms.Label();
            this.textBox10 = new System.Windows.Forms.TextBox();
            this.label8 = new System.Windows.Forms.Label();
            this.tabControl1.SuspendLayout();
            this.tabPage1.SuspendLayout();
            this.tabPage2.SuspendLayout();
            this.SuspendLayout();
            //
            // tabControl1
            //
            this.tabControl1.Controls.Add(this.tabPage1);
            this.tabControl1.Controls.Add(this.tabPage2);
            this.tabControl1.Location = new System.Drawing.Point(3, 2);
            this.tabControl1.Name = "tabControl1";
            this.tabControl1.SelectedIndex = 0;
            this.tabControl1.Size = new System.Drawing.Size(790, 639);
            this.tabControl1.TabIndex = 0;
            //
            // tabPage1
            //
            this.tabPage1.Controls.Add(this.textBox6);
            this.tabPage1.Controls.Add(this.textBox5);
            this.tabPage1.Controls.Add(this.button3);
            this.tabPage1.Controls.Add(this.radioButton2);
            this.tabPage1.Controls.Add(this.radioButton1);
            this.tabPage1.Controls.Add(this.button2);
            this.tabPage1.Controls.Add(this.button1);
            this.tabPage1.Controls.Add(this.textBox4);
            this.tabPage1.Controls.Add(this.label4);
            this.tabPage1.Controls.Add(this.textBox3);
            this.tabPage1.Controls.Add(this.label3);
            this.tabPage1.Controls.Add(this.textBox2);
            this.tabPage1.Controls.Add(this.label2);
            this.tabPage1.Controls.Add(this.textBox1);
            this.tabPage1.Controls.Add(this.label1);
            this.tabPage1.Location = new System.Drawing.Point(4, 22);
            this.tabPage1.Name = "tabPage1";
            this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage1.Size = new System.Drawing.Size(782, 613);
            this.tabPage1.TabIndex = 0;
            this.tabPage1.Text = "Receive";
            this.tabPage1.UseVisualStyleBackColor = true;
            //
            // textBox6
            //
            this.textBox6.Location = new System.Drawing.Point(28, 271);
            this.textBox6.Multiline = true;
            this.textBox6.Name = "textBox6";
            this.textBox6.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.textBox6.Size = new System.Drawing.Size(729, 330);
            this.textBox6.TabIndex = 14;
            //
            // textBox5
            //
            this.textBox5.Location = new System.Drawing.Point(231, 232);
            this.textBox5.Name = "textBox5";
            this.textBox5.Size = new System.Drawing.Size(39, 20);
            this.textBox5.TabIndex = 13;
            //
            // button3
            //
            this.button3.Location = new System.Drawing.Point(150, 230);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(75, 23);
            this.button3.TabIndex = 12;
            this.button3.Text = "Get Email";
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button3_Click);
            //
            // radioButton2
            //
            this.radioButton2.AutoSize = true;
            this.radioButton2.Location = new System.Drawing.Point(119, 137);
            this.radioButton2.Name = "radioButton2";
            this.radioButton2.Size = new System.Drawing.Size(51, 17);
            this.radioButton2.TabIndex = 11;
            this.radioButton2.TabStop = true;
            this.radioButton2.Text = "IMAP";
            this.radioButton2.UseVisualStyleBackColor = true;
            //
            // radioButton1
            //
            this.radioButton1.AutoSize = true;
            this.radioButton1.Checked = true;
            this.radioButton1.Location = new System.Drawing.Point(28, 137);
            this.radioButton1.Name = "radioButton1";
            this.radioButton1.Size = new System.Drawing.Size(53, 17);
            this.radioButton1.TabIndex = 10;
            this.radioButton1.TabStop = true;
            this.radioButton1.Text = "POP3";
            this.radioButton1.UseVisualStyleBackColor = true;
            //
            // button2
            //
            this.button2.Location = new System.Drawing.Point(28, 230);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 23);
            this.button2.TabIndex = 9;
            this.button2.Text = "List Emails";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            //
            // button1
            //
            this.button1.Location = new System.Drawing.Point(28, 170);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 8;
            this.button1.Text = "Connect";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            //
            // textBox4
            //
            this.textBox4.Location = new System.Drawing.Point(90, 98);
            this.textBox4.Name = "textBox4";
            this.textBox4.Size = new System.Drawing.Size(135, 20);
            this.textBox4.TabIndex = 7;
            //
            // label4
            //
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(25, 101);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(53, 13);
            this.label4.TabIndex = 6;
            this.label4.Text = "Password";
            //
            // textBox3
            //
            this.textBox3.Location = new System.Drawing.Point(90, 72);
            this.textBox3.Name = "textBox3";
            this.textBox3.Size = new System.Drawing.Size(135, 20);
            this.textBox3.TabIndex = 5;
            //
            // label3
            //
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(25, 75);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(55, 13);
            this.label3.TabIndex = 4;
            this.label3.Text = "Username";
            //
            // textBox2
            //
            this.textBox2.Location = new System.Drawing.Point(90, 46);
            this.textBox2.Name = "textBox2";
            this.textBox2.Size = new System.Drawing.Size(135, 20);
            this.textBox2.TabIndex = 3;
            //
            // label2
            //
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(25, 49);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(26, 13);
            this.label2.TabIndex = 2;
            this.label2.Text = "Port";
            //
            // textBox1
            //
            this.textBox1.Location = new System.Drawing.Point(90, 19);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(135, 20);
            this.textBox1.TabIndex = 1;
            //
            // label1
            //
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(25, 22);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(38, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "Server";
            //
            // tabPage2
            //
            this.tabPage2.Controls.Add(this.textBox13);
            this.tabPage2.Controls.Add(this.label11);
            this.tabPage2.Controls.Add(this.button5);
            this.tabPage2.Controls.Add(this.textBox12);
            this.tabPage2.Controls.Add(this.label10);
            this.tabPage2.Controls.Add(this.textBox11);
            this.tabPage2.Controls.Add(this.label9);
            this.tabPage2.Controls.Add(this.textBox7);
            this.tabPage2.Controls.Add(this.label5);
            this.tabPage2.Controls.Add(this.textBox8);
            this.tabPage2.Controls.Add(this.label6);
            this.tabPage2.Controls.Add(this.textBox9);
            this.tabPage2.Controls.Add(this.label7);
            this.tabPage2.Controls.Add(this.textBox10);
            this.tabPage2.Controls.Add(this.label8);
            this.tabPage2.Location = new System.Drawing.Point(4, 22);
            this.tabPage2.Name = "tabPage2";
            this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage2.Size = new System.Drawing.Size(782, 613);
            this.tabPage2.TabIndex = 1;
            this.tabPage2.Text = "Send";
            this.tabPage2.UseVisualStyleBackColor = true;
            //
            // textBox13
            //
            this.textBox13.Location = new System.Drawing.Point(90, 190);
            this.textBox13.Name = "textBox13";
            this.textBox13.Size = new System.Drawing.Size(135, 20);
            this.textBox13.TabIndex = 24;
            //
            // label11
            //
            this.label11.AutoSize = true;
            this.label11.Location = new System.Drawing.Point(25, 193);
            this.label11.Name = "label11";
            this.label11.Size = new System.Drawing.Size(43, 13);
            this.label11.TabIndex = 23;
            this.label11.Text = "Subject";
            //
            // button5
            //
            this.button5.Location = new System.Drawing.Point(90, 579);
            this.button5.Name = "button5";
            this.button5.Size = new System.Drawing.Size(85, 22);
            this.button5.TabIndex = 22;
            this.button5.Text = "Send";
            this.button5.UseVisualStyleBackColor = true;
            this.button5.Click += new System.EventHandler(this.button5_Click);
            //
            // textBox12
            //
            this.textBox12.Location = new System.Drawing.Point(90, 225);
            this.textBox12.Multiline = true;
            this.textBox12.Name = "textBox12";
            this.textBox12.Size = new System.Drawing.Size(657, 335);
            this.textBox12.TabIndex = 21;
            //
            // label10
            //
            this.label10.AutoSize = true;
            this.label10.Location = new System.Drawing.Point(25, 225);
            this.label10.Name = "label10";
            this.label10.Size = new System.Drawing.Size(28, 13);
            this.label10.TabIndex = 20;
            this.label10.Text = "Text";
            //
            // textBox11
            //
            this.textBox11.Location = new System.Drawing.Point(90, 161);
            this.textBox11.Name = "textBox11";
            this.textBox11.Size = new System.Drawing.Size(135, 20);
            this.textBox11.TabIndex = 19;
            //
            // label9
            //
            this.label9.AutoSize = true;
            this.label9.Location = new System.Drawing.Point(25, 164);
            this.label9.Name = "label9";
            this.label9.Size = new System.Drawing.Size(50, 13);
            this.label9.TabIndex = 18;
            this.label9.Text = "Receiver";
            //
            // textBox7
            //
            this.textBox7.Location = new System.Drawing.Point(90, 98);
            this.textBox7.Name = "textBox7";
            this.textBox7.Size = new System.Drawing.Size(135, 20);
            this.textBox7.TabIndex = 16;
            //
            // label5
            //
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(25, 101);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(53, 13);
            this.label5.TabIndex = 15;
            this.label5.Text = "Password";
            //
            // textBox8
            //
            this.textBox8.Location = new System.Drawing.Point(90, 72);
            this.textBox8.Name = "textBox8";
            this.textBox8.Size = new System.Drawing.Size(135, 20);
            this.textBox8.TabIndex = 14;
            //
            // label6
            //
            this.label6.AutoSize = true;
            this.label6.Location = new System.Drawing.Point(25, 75);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(55, 13);
            this.label6.TabIndex = 13;
            this.label6.Text = "Username";
            //
            // textBox9
            //
            this.textBox9.Location = new System.Drawing.Point(90, 46);
            this.textBox9.Name = "textBox9";
            this.textBox9.Size = new System.Drawing.Size(135, 20);
            this.textBox9.TabIndex = 12;
            //
            // label7
            //
            this.label7.AutoSize = true;
            this.label7.Location = new System.Drawing.Point(25, 49);
            this.label7.Name = "label7";
            this.label7.Size = new System.Drawing.Size(26, 13);
            this.label7.TabIndex = 11;
            this.label7.Text = "Port";
            //
            // textBox10
            //
            this.textBox10.Location = new System.Drawing.Point(90, 19);
            this.textBox10.Name = "textBox10";
            this.textBox10.Size = new System.Drawing.Size(135, 20);
            this.textBox10.TabIndex = 10;
            //
            // label8
            //
            this.label8.AutoSize = true;
            this.label8.Location = new System.Drawing.Point(25, 22);
            this.label8.Name = "label8";
            this.label8.Size = new System.Drawing.Size(38, 13);
            this.label8.TabIndex = 9;
            this.label8.Text = "Server";
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(788, 637);
            this.Controls.Add(this.tabControl1);
            this.Name = "Form1";
            this.Text = "Emails";
            this.tabControl1.ResumeLayout(false);
            this.tabPage1.ResumeLayout(false);
            this.tabPage1.PerformLayout();
            this.tabPage2.ResumeLayout(false);
            this.tabPage2.PerformLayout();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.TabControl tabControl1;
        private System.Windows.Forms.TabPage tabPage1;
        private System.Windows.Forms.RadioButton radioButton2;
        private System.Windows.Forms.RadioButton radioButton1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.TextBox textBox4;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox textBox3;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.TextBox textBox2;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TabPage tabPage2;
        private System.Windows.Forms.TextBox textBox6;
        private System.Windows.Forms.TextBox textBox5;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.TextBox textBox12;
        private System.Windows.Forms.Label label10;
        private System.Windows.Forms.TextBox textBox11;
        private System.Windows.Forms.Label label9;
        private System.Windows.Forms.TextBox textBox7;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.TextBox textBox8;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.TextBox textBox9;
        private System.Windows.Forms.Label label7;
        private System.Windows.Forms.TextBox textBox10;
        private System.Windows.Forms.Label label8;
        private System.Windows.Forms.Button button5;
        private System.Windows.Forms.TextBox textBox13;
        private System.Windows.Forms.Label label11;



    }
}