C# - Crear un servidor SMTP

Iniciado por TickTack, 17 Julio 2018, 13:40 PM

0 Miembros y 1 Visitante están viendo este tema.

TickTack

Hola a todos,

trate de crear un servidor SMTP con este codigo:


IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 25);
TcpListener listener = new TcpListener(endPoint);
listener.Start();

while (true)
{
    TcpClient client = listener.AcceptTcpClient();
    SMTPServer handler = new SMTPServer();
    servers.Add(handler);
    handler.Init(client);
    Thread thread = new System.Threading.Thread(new ThreadStart(handler.Run));
    thread.Start();
}

public void Run()
{
    Write("220 localhost -- Fake proxy server");
    string strMessage = String.Empty;
    while (true)
    {
        try
        {
            strMessage = Read();
        }
        catch(Exception e)
        {
            //a socket error has occured
            break;
        }

        if (strMessage.Length > 0)
        {
            if (strMessage.StartsWith("QUIT"))
            {
                client.Close();
                break;//exit while
            }
            //message has successfully been received
            if (strMessage.StartsWith("EHLO"))
            {
                Write("250 OK");
            }

            if (strMessage.StartsWith("RCPT TO"))
            {
                Write("250 OK");
            }

            if (strMessage.StartsWith("MAIL FROM"))
            {

               Write("250 OK");
            }

            if (strMessage.StartsWith("DATA"))
            {
                Write("354 Start mail input; end with");
                strMessage = Read();
                Write("250 OK");
            }
        } 
    }
}

private void Write(String strMessage)
{
    NetworkStream clientStream = client.GetStream();
    ASCIIEncoding encoder = new ASCIIEncoding();
    byte[] buffer = encoder.GetBytes(strMessage + "\r\n");
   
    clientStream.Write(buffer, 0, buffer.Length);
    clientStream.Flush();
}

private String Read()
{
    byte[] messageBytes = new byte[8192];
    int bytesRead = 0;
    NetworkStream clientStream = client.GetStream();
    ASCIIEncoding encoder = new ASCIIEncoding();
    bytesRead = clientStream.Read(messageBytes, 0, 8192);
    string strMessage = encoder.GetString(messageBytes, 0, bytesRead);
    return strMessage;
}


Pero me larga error. Me dice que no se encontró SMTPServer.

Que puedo hacer? De donde puedo obtener la clase SMTPServer?


Gracias y saludos
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

Shell Root

Por eso no duermo, por si tras mi ventana hay un cuervo. Cuelgo de hilos sueltos sabiendo que hay veneno en el aire.

TickTack

Hola Shell Root,

Utilice el proyecto que tu me mostraste.

Según el autor, hay que usar este código:


var options = new SmtpServerOptionsBuilder()
   .ServerName("localhost")
   .Port(25, 587)
   .Build();

var smtpServer = new SmtpServer.SmtpServer(options);
await smtpServer.StartAsync(CancellationToken.None);


Pero cuando quiero iniciar la consola, se abre y se cierra.

En el reporte de salida, me larga esto:

Citar
"E-Mail Server.exe" (CLR v4.0.30319: DefaultDomain): "C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll" cargado. La carga de simbolos fue omitida. El modulo esta optimizado, y la opción de depuración "Solamente código propio" esta activado.
"E-Mail Server.exe" (CLR v4.0.30319: DefaultDomain): "C:\Users\X61s\source\repos\E-Mail Server\E-Mail Server\bin\Debug\E-Mail Server.exe" cargado. Los simbolos se han cargado.
"E-Mail Server.exe" (CLR v4.0.30319: E-Mail Server.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll" cargado. La carga de simbolos fue omitida. El modulo esta optimizado, y la opción de depuración "Solamente código propio" esta activado.
"E-Mail Server.exe" (CLR v4.0.30319: E-Mail Server.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll" cargado. La carga de simbolos fue omitida. El modulo esta optimizado, y la opción de depuración "Solamente código propio" esta activado.
"E-Mail Server.exe" (CLR v4.0.30319: E-Mail Server.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll" cargado. La carga de simbolos fue omitida. El modulo esta optimizado, y la opción de depuración "Solamente código propio" esta activado.
"E-Mail Server.exe" (CLR v4.0.30319: E-Mail Server.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll" cargado. La carga de simbolos fue omitida. El modulo esta optimizado, y la opción de depuración "Solamente código propio" esta activado.
El programa "[5820] E-Mail Server.exe" finalizó con el código 0 (0x0).

Luego pensé que se debía a que la opción de depuración "Solamente código propio" estaba activada; así que la desactive y volví a iniciar la consola y entonces vuelve a pasar lo mismo (La consola se abre y se cierra) y el reporte de salida me larga esto:

Citar
"E-Mail Server.exe" (CLR v4.0.30319: DefaultDomain): "C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll" cargado. El dato PDB no se ha encontrado o no se pudo abrir.
"E-Mail Server.exe" (CLR v4.0.30319: DefaultDomain): "C:\Users\X61s\source\repos\E-Mail Server\E-Mail Server\bin\Debug\E-Mail Server.exe" cargado. Los simbolos se han cargado.
"E-Mail Server.exe" (CLR v4.0.30319: E-Mail Server.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll" cargado. El dato PDB no se ha encontrado o no se pudo abrir.
"E-Mail Server.exe" (CLR v4.0.30319: E-Mail Server.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll" cargado. El dato PDB no se ha encontrado o no se pudo abrir.
"E-Mail Server.exe" (CLR v4.0.30319: E-Mail Server.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll" cargado. El dato PDB no se ha encontrado o no se pudo abrir.
"E-Mail Server.exe" (CLR v4.0.30319: E-Mail Server.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll" cargado. El dato PDB no se ha encontrado o no se pudo abrir.
Das Programm "[4440] E-Mail Server.exe" wurde mit Code 0 (0x0) beendet.
El programa "[5820] E-Mail Server.exe" finalizó con el código 0 (0x0).

Luego me fije en la carpeta en donde se encuentra la aplicación consola y allí estaba el dato PDB.

Así que no se realmente lo que esta pasando. Alguien me puede ayudar, por favor?

Gracias y saludos

PS.: El código de mi aplicación consola es este:


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

namespace E_Mail_Server
{
   class Program
   {
       static void Main(string[] args)
       {
           StartAsync();
       }

       public static async void StartAsync()
       {
           var options = new SmtpServerOptionsBuilder()
               .ServerName("localhost")
               .Port(25, 587)
               .Build();
           var smtpServer = new SmtpServer.SmtpServer(options);
           await smtpServer.StartAsync(CancellationToken.None);
       }
   }
}
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

TickTack

Hola a todos,

ya arregle el problema de que la consola se cierra.

Pero ahora tengo el problema de que no puedo enviar E-Mails.

El código del cliente es este mas o menos:


SmtpClient smtpClient = new SmtpClient();
            smtpClient.Host = "localhost";
            smtpClient.Port = 587;
            smtpClient.Send(new MailMessage("app@AIKI.CO.ir", "qermezkon@gmail.com")
            {
                Subject = "Test",
                Body = "test"
            });


Queria habilitar un seguimiento para poder obtener eventos y tengo este codigo de parte del servidor:


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

namespace E_Mail_Server
{
    class Program
    {
        static CancellationTokenSource _cancellationTokenSource;

        static void Main(string[] args)
        {
            StartAsync().Wait();
        }

        public static async Task StartAsync()
        {
            _cancellationTokenSource = new CancellationTokenSource();

            var options = new SmtpServerOptionsBuilder()
                .ServerName("localhost")
                .Port(25, 587)
                .Build();
            var server = new SmtpServer.SmtpServer(options);

            server.SessionCreated += OnSessionCreated;
            server.SessionCompleted += OnSessionCompleted;

            var serverTask = server.StartAsync(_cancellationTokenSource.Token);

            serverTask.WaitWithoutException();
        }

        static void OnSessionCreated(object sender, SessionEventArgs e)
        {
            Console.WriteLine("SessionCreated: {0}", e.Context.RemoteEndPoint);

            e.Context.CommandExecuting += OnCommandExecuting;
        }

        static void OnSessionCompleted(object sender, SessionEventArgs e)
        {
            Console.WriteLine("SessionCompleted: {0}", e.Context.RemoteEndPoint);

            e.Context.CommandExecuting -= OnCommandExecuting;

            _cancellationTokenSource.Cancel();
        }
    }
}


Pero Visual Studio me dice lo siguiente:

Citar
"Task" no contiene una definición para "WaitWithoutException", y no se pudo encontrar ningún método WaitWithoutException que acepte un primer argumento de tipo "Task" (puede que falte una directiva using o una referencia de ensamblaje).

No entiendo. No se porque se habla de "Task" ahora.

Alguien me puede ayudar?

Gracias y saludos
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

Eleкtro

#4
Por lo que veo estás utilizando una clase/librería de terceros que se llama "smtpServer" y basicamente lo que el error te dice es que no se puede encontrar ninguna definición de un método con el nombre "WaitWithoutException" puesto que dicho método no forma parte de la librería de clases de .NET Framework ni tampoco del código fuente principal de esa tal libreria "smtpServer", sino que el autor ha definido ese método en el código fuente de la aplicación de muestra:


Espero que se me haya entendido bien. Y dicho esto, me parece que @Shell Root te ha podido llegar a confundir un poco por que primero te entregó instrucciones sobre el espacio de nombres System.Net.Mail de .NET Framework que es donde se haya la clase SmtpClient (que es lo único que alguien debe necesitar si la única intención fuese enviar mails mediante SMTP) pero luego te entregó un enlace a una librería de terceros que nada tiene que ver con lo primero... me refiero, por que es de terceros.

Saludos.








TickTack

Hola Elektro,

Mis agradecimientos por ayudarme. Veras: pude arreglar el problema del "Task". Sigo sin
poder enviar E-Mails pero logre capturar unos seguimientos.

Mi codigo, ahora, es este:


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

namespace E_Mail_Server
{
   public static class Program
   {
       static CancellationTokenSource _cancellationTokenSource;

       static void Main(string[] args)
       {
           StartAsync().Wait();
       }

       public static async Task StartAsync()
       {
           _cancellationTokenSource = new CancellationTokenSource();

           var options = new SmtpServerOptionsBuilder()
               .ServerName("localhost")
               .Port(25, 587)
               .Build();
           var server = new SmtpServer.SmtpServer(options);

           server.SessionCreated += OnSessionCreated;
           server.SessionCompleted += OnSessionCompleted;

           var serverTask = server.StartAsync(_cancellationTokenSource.Token);

           WaitWithoutException(serverTask);
       }

       static void OnSessionCreated(object sender, SessionEventArgs e)
       {
           Console.WriteLine("SessionCreated: {0}", e.Context.RemoteEndPoint);

           e.Context.CommandExecuting += OnCommandExecuting;
       }

       static void OnSessionCompleted(object sender, SessionEventArgs e)
       {
           Console.WriteLine("SessionCompleted: {0}", e.Context.RemoteEndPoint);

           e.Context.CommandExecuting -= OnCommandExecuting;

           _cancellationTokenSource.Cancel();
       }

       static void OnCommandExecuting(object sender, SmtpCommandExecutingEventArgs e)
       {
           new TracingSmtpCommandVisitor(Console.Out).Visit(e.Command);
       }

       public static void WaitWithoutException(this Task task)
       {
           try
           {
               task.Wait();
           }
           catch (AggregateException e)
           {
               e.Handle(exception => exception is OperationCanceledException);
           }
       }
   }
}


Y estos son los eventos de seguimientos que capture:

Citar
SessionCreated: 127.0.0.1:49510
EHLO: DomainOrAddress=X61s-PC
MAIL: Address=app@AIKI.CO.ir Parameters=
RCPT: Address=nemoschmidt7@gmail.com
DATA

Pero despues de un tiempo la consola se cierra. El reporte de salida es este:

Citar
Excepción activada: "System.OperationCanceledException" en SmtpServer.dll
Excepción activada: "System.OperationCanceledException" en mscorlib.dll
Excepción activada: "System.OperationCanceledException" en SmtpServer.dll
Excepción activada: "System.ObjectDisposedException" en System.dll
Excepción activada: "System.OperationCanceledException" en mscorlib.dll
Excepción activada: "System.OperationCanceledException" en mscorlib.dll
Excepción activada: "System.ObjectDisposedException" en System.dll
Excepción activada: "System.AggregateException" en mscorlib.dll
El programa "[8000] E-Mail Server.exe" ha finalizado con codigo 0 (0x0).

Nuevamente muchas gracias por tu ayuda.

Gracias y saludos
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

rigorvzla


TickTack

Hola rigorvzla,

El link que tu me pasaste se trata de un Cliente SMTP. Pero yo queria hacer un Servidor SMTP.

Gracias y saludos
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."