测试SMTP服务器正在通过C#运行

如何在不发送消息的情况下通过C#测试SMTP是否正常运行。

我当然可以尝试:

try{ // send email to "nonsense@example.com" } catch { // log "smtp is down" } 

必须有一个更整洁的方法来做到这一点。

您可以尝试向服务器说EHLO ,看看它是否以250 OK响应。 当然,这个测试并不能保证您以后会成功发送邮件,但这是一个很好的指示。

以下是一个示例:

 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 } } } } } 

这是预期的代码列表 。

我使用此方法和类来validation凭据( 链接到github ):

 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(); } } 

您可以使用套接字或TcpClient打开端口(25),看看它是否响应。

在端口25上打开到smtp服务器的套接字连接,看看你是否得到任何东西。 如果没有,没有smtp服务器。

这是一个很好的开源工具(比MX更多): http : //www.codeproject.com/KB/IP/DNS_NET_Resolver.aspx