2009-10-27 18 views

Antwort

51

Sie können versuchen saying EHLO zu Ihrem Server und sehen, ob es mit 250 OK reagiert. Natürlich garantiert Ihnen dieser Test nicht, dass Sie die Mail später versenden werden, aber es ist ein guter Hinweis.

Und hier ist ein Beispiel:

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var client = new TcpClient()) 
     { 
      var server = "smtp.gmail.com"; 
      var port = 465; 
      client.Connect(server, port); 
      // As GMail requires SSL we should use SslStream 
      // If your SMTP server doesn't support SSL you can 
      // work directly with the underlying stream 
      using (var stream = client.GetStream()) 
      using (var sslStream = new SslStream(stream)) 
      { 
       sslStream.AuthenticateAsClient(server); 
       using (var writer = new StreamWriter(sslStream)) 
       using (var reader = new StreamReader(sslStream)) 
       { 
        writer.WriteLine("EHLO " + server); 
        writer.Flush(); 
        Console.WriteLine(reader.ReadLine()); 
        // GMail responds with: 220 mx.google.com ESMTP 
       } 
      } 
     } 
    } 
} 

Und hier ist die list of codes zu erwarten.

+2

+1: Sehr elegant, das Protokoll funktioniert nicht richtig. –

+0

Ich mag es - ich mag es sehr! Guter Mann! – Vidar

+0

@Darin Dimitrov tanx für Ihre Antwort .. Gibt es trotzdem zu ckeck Benutzername & Passwort (SMTP-Authentifizierung) ist gültig? Ich fragte es in http://stackoverflow.com/questions/17319276/how-can-i-check-smtp-server-without-sending-email .. bitte helfen Sie mir –

3

Sie könnten den Port (25) mit einer Buchse oder TcpClient öffnen und sehen, ob er antwortet.

3

Öffnen Sie eine Socket-Verbindung zum SMTP-Server an Port 25 und sehen Sie, ob Sie etwas bekommen. Wenn nicht, kein SMTP-Server.

5

Ich benutze diese Methode und Klassen die Anmeldeinformationen (link to github) zu validieren:

public static bool ValidateCredentials(string login, string password, string server, int port, bool enableSsl) { 
     SmtpConnectorBase connector; 
     if (enableSsl) { 
      connector = new SmtpConnectorWithSsl(server, port); 
     } else { 
      connector = new SmtpConnectorWithoutSsl(server, port); 
     } 

     if (!connector.CheckResponse(220)) { 
      return false; 
     } 

     connector.SendData($"HELO {Dns.GetHostName()}{SmtpConnectorBase.EOF}"); 
     if (!connector.CheckResponse(250)) { 
      return false; 
     } 

     connector.SendData($"AUTH LOGIN{SmtpConnectorBase.EOF}"); 
     if (!connector.CheckResponse(334)) { 
      return false; 
     } 

     connector.SendData(Convert.ToBase64String(Encoding.UTF8.GetBytes($"{login}")) + SmtpConnectorBase.EOF); 
     if (!connector.CheckResponse(334)) { 
      return false; 
     } 

     connector.SendData(Convert.ToBase64String(Encoding.UTF8.GetBytes($"{password}")) + SmtpConnectorBase.EOF); 
     if (!connector.CheckResponse(235)) { 
      return false; 
     } 

     return true; 
    } 

SmtpConnectorBase:

internal abstract class SmtpConnectorBase { 
    protected string SmtpServerAddress { get; set; } 
    protected int Port { get; set; } 
    public const string EOF = "\r\n"; 

    protected SmtpConnectorBase(string smtpServerAddress, int port) { 
     SmtpServerAddress = smtpServerAddress; 
     Port = port; 
    } 

    public abstract bool CheckResponse(int expectedCode); 
    public abstract void SendData(string data); 
} 

SmtpConnectorWithoutSsl:

internal class SmtpConnectorWithoutSsl : SmtpConnectorBase { 
    private Socket _socket = null; 

    public SmtpConnectorWithoutSsl(string smtpServerAddress, int port) : base(smtpServerAddress, port) { 
     IPHostEntry hostEntry = Dns.GetHostEntry(smtpServerAddress); 
     IPEndPoint endPoint = new IPEndPoint(hostEntry.AddressList[0], port); 
     _socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
     //try to connect and test the rsponse for code 220 = success 
     _socket.Connect(endPoint); 

    } 

    ~SmtpConnectorWithoutSsl() { 
     try { 
      if (_socket != null) { 
       _socket.Close(); 
       _socket.Dispose(); 
       _socket = null; 
      } 
     } catch (Exception) { 
      ; 
     } 

    } 

    public override bool CheckResponse(int expectedCode) { 
     while (_socket.Available == 0) { 
      System.Threading.Thread.Sleep(100); 
     } 
     byte[] responseArray = new byte[1024]; 
     _socket.Receive(responseArray, 0, _socket.Available, SocketFlags.None); 
     string responseData = Encoding.UTF8.GetString(responseArray); 
     int responseCode = Convert.ToInt32(responseData.Substring(0, 3)); 
     if (responseCode == expectedCode) { 
      return true; 
     } 
     return false; 
    } 

    public override void SendData(string data) { 
     byte[] dataArray = Encoding.UTF8.GetBytes(data); 
     _socket.Send(dataArray, 0, dataArray.Length, SocketFlags.None); 
    } 
} 

SmtpConnectorWithSsl:

internal class SmtpConnectorWithSsl : SmtpConnectorBase { 
    private SslStream _sslStream = null; 
    private TcpClient _client = null; 

    public SmtpConnectorWithSsl(string smtpServerAddress, int port) : base(smtpServerAddress, port) { 
     TcpClient client = new TcpClient(smtpServerAddress, port); 

     _sslStream = new SslStream(
      client.GetStream(), 
      false, 
      new RemoteCertificateValidationCallback(ValidateServerCertificate), 
      null 
      ); 
     // The server name must match the name on the server certificate. 
     try { 
      _sslStream.AuthenticateAsClient(smtpServerAddress); 
     } catch (AuthenticationException e) { 
      _sslStream = null; 
      Console.WriteLine("Exception: {0}", e.Message); 
      if (e.InnerException != null) { 
       Console.WriteLine("Inner exception: {0}", e.InnerException.Message); 
      } 
      Console.WriteLine("Authentication failed - closing the connection."); 
      client.Close(); 
     } 
    } 

    ~SmtpConnectorWithSsl() { 
     try { 
      if (_sslStream != null) { 
       _sslStream.Close(); 
       _sslStream.Dispose(); 
       _sslStream = null; 
      } 
     } catch (Exception) { 
      ; 
     } 

     try { 
      if (_client != null) { 
       _client.Close(); 
       _client = null; 
      } 
     } catch (Exception) { 
      ; 
     } 
    } 

    // The following method is invoked by the RemoteCertificateValidationDelegate. 
    private static bool ValidateServerCertificate(
      object sender, 
      X509Certificate certificate, 
      X509Chain chain, 
      SslPolicyErrors sslPolicyErrors) { 
     if (sslPolicyErrors == SslPolicyErrors.None) 
      return true; 

     Console.WriteLine("Certificate error: {0}", sslPolicyErrors); 

     // Do not allow this client to communicate with unauthenticated servers. 
     return false; 
    } 

    public override bool CheckResponse(int expectedCode) { 
     if (_sslStream == null) { 
      return false; 
     } 
     var message = ReadMessageFromStream(_sslStream); 
     int responseCode = Convert.ToInt32(message.Substring(0, 3)); 
     if (responseCode == expectedCode) { 
      return true; 
     } 
     return false; 
    } 

    public override void SendData(string data) { 
     byte[] messsage = Encoding.UTF8.GetBytes(data); 
     // Send hello message to the server. 
     _sslStream.Write(messsage); 
     _sslStream.Flush(); 
    } 

    private string ReadMessageFromStream(SslStream stream) { 
     byte[] buffer = new byte[2048]; 
     StringBuilder messageData = new StringBuilder(); 
     int bytes = -1; 
     do { 
      bytes = stream.Read(buffer, 0, buffer.Length); 

      // Use Decoder class to convert from bytes to UTF8 
      // in case a character spans two buffers. 
      Decoder decoder = Encoding.UTF8.GetDecoder(); 
      char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)]; 
      decoder.GetChars(buffer, 0, bytes, chars, 0); 
      messageData.Append(chars); 
      // Check for EOF. 
      if (messageData.ToString().IndexOf(EOF) != -1) { 
       break; 
      } 
     } while (bytes != 0); 

     return messageData.ToString(); 
    } 
} 
+0

Jetzt verwende ich diese Bibliothek https://github.com/jstedfast/MimeKit –

+1

gibt es eine Endlosschleife in SmtpConnectorWithoutSsl. In der CheckResponse-Methode sollte die Zeile while (_socket.Available == 0) ein Limit haben. Ich traf ein Szenario, in dem _socket.Available wurde nie etwas anderes als 0 aber davon abgesehen - das funktioniert perfekt. benutze es seit ungefähr 6 Monaten ohne Problem. –