.Net TcpClient and SmtpClient won't connect to

2019-09-18 10:42发布

问题:

I have a method that is supposed to connect to an Smtp Server to see if it is online. This method works when testing many mail servers, but not all of them. The code is below, however the failure happens on...

client.Connect(strMailServer, intPort);

... before the logic of talking to the server even begins. It simply won't connect. I've made absolutely sure I'm connecting the the right IP and port (25), and I've used third party web sites like mxtoolbox to test the same server IP with success. This server is receiving regular traffic from the world wide web... only .Net seems unable to connect. I've reviewed firewall rules, and watched with WireShark to see what is happening on the server, but I never see any incoming packets from my test runs. The Firewall is set to allow all connections to port 25 on all interfaces, from anybody.

I've also used SmtpClient to run a similar test shown below, it fails as well.

                var client = new System.Net.Mail.SmtpClient(strMailServer, intPort);
            client.Send("test@mydomain.com", "test@mydomain.com", "test message", "This is meant to test an SMTP server to see if it is online, it expects the message to be rejected.");

The error stack here leads to the same underying error as my TcpClient attempt. SocketException: {"No connection could be made because the target machine actively refused it xxx.xxx.xxx.xxx:25"}

How could everybody in the world be able to connect to this server... except for my laptop computer... I don't think this is a firewall issue.

Help!

public static bool TestMailServer(string strMailServer, int intPort, out string strResponse)
    {
        try
        {
            try
            {
                //First I'll try a basic SMTP HELO
                using (var client = new TcpClient())
                {
                    client.Connect(strMailServer, intPort);
                    // 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 writer = new StreamWriter(stream))
                        using (var reader = new StreamReader(stream))
                        {
                            writer.WriteLine("EHLO " + strMailServer);
                            writer.Flush();
                            strResponse = reader.ReadLine();
                            if (strResponse == null)
                                throw new Exception("No Valid Connection");

                            stream.Close();
                            client.Close();
                            if (F.StartsWith(strResponse, "220"))
                                return true;
                            else
                                return false;
                        }

                    }

                }
            }
            catch (Exception ex)
            {
                //If the above failed, I'll try with SSL
                using (var client = new TcpClient())
                {
                    //var server = "smtp.gmail.com";
                    //var port = 465;
                    //client.SendTimeout = 10000;
                    //client.ReceiveTimeout = 10000;

                    client.Connect(strMailServer, intPort);
                    // 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(strMailServer);
                        using (var writer = new StreamWriter(sslStream))
                        using (var reader = new StreamReader(sslStream))
                        {
                            writer.WriteLine("EHLO " + strMailServer);
                            writer.Flush();

                            strResponse = reader.ReadLine();
                            if (strResponse == null)
                                throw new Exception("No Valid Connection");

                            stream.Close();
                            client.Close();
                            if (F.StartsWith(strResponse, "220"))
                                return true;
                            else
                                return false;
                            // GMail responds with: 220 mx.google.com ESMTP
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            strResponse = ex.Message;
            return false;
        }
    }

回答1:

"The target machine actively refused it" means there is nothing listening on port 25 - you sent a SYN packet and got back RST instead of SYN/ACK.

If you don't even see the SYN in your wireshark capture, perhaps your laptop is resolving the name incorrectly. Are you connecting to the server by name or IP? Have you tried a simple

telnet mailhost 25

to see if that connects?



回答2:

Normally to prevent SMTP server sending anonymous e-mails, they will accept a connection only after successful reverse DNS lookup on the inbound ip address. I believe the reverse DNS lookup of your home address fails so it has dropped the connection.



回答3:

The answer was so simple I slapped myself with I realized... My ISP is blocking all connections on port 25, inbound and outbound. As soon as I moved to a different location everything worked. Duh!!

http://www.cox.com/residential/support/internet/article.cox?articleId=cacf82f0-6407-11df-ccef-000000000000

For whoever might want it, here is my SMTPTest class that will probe a server for SMTP capability. I use it to monitor my servers, report outages, and validate user input of server info.

public struct SMTPTestResult
{
    public string Server;
    public bool Found;
    public bool OriginalPortSuccess;
    public int FinalPort;
    public bool UsedSSL;
    public string Response;
}

public class SMTPTest
{
    public static SMTPTestResult TestMailServer(string MailServer)
    {
        return TestMailServer(MailServer, 25, true);
    }

    public static SMTPTestResult TestMailServer(string MailServer, int Port, bool TryOtherPorts)
    {
        SMTPTestResult result = new SMTPTestResult();
        result.Server = MailServer;

        if (AttemptMailServer(MailServer, Port, false, out result.Response))
        {
            //First try the requested port, without SSL.
            result.Found = true;
            result.UsedSSL = false;
            result.OriginalPortSuccess = true;
            result.FinalPort = Port;
            return result;
        }
        else if (AttemptMailServer(MailServer, Port, true, out result.Response))
        {
            //Try the requested port, with SSL.
            result.Found = true;
            result.UsedSSL = true;
            result.OriginalPortSuccess = true;
            result.FinalPort = Port;
            return result;
        }
        else if (TryOtherPorts && Port != 465 && AttemptMailServer(MailServer, 465, true, out result.Response))
        {
            //Try port 465 with SSL
            result.Found = true;
            result.UsedSSL = true;
            result.OriginalPortSuccess = false;
            result.FinalPort = 465;
            return result;
        }
        else if (TryOtherPorts && Port != 25 && AttemptMailServer(MailServer, 25, false, out result.Response))
        {
            //Try port 25, without SSL.
            result.Found = true;
            result.UsedSSL = false;
            result.OriginalPortSuccess = false;
            result.FinalPort = 25;
            return result;
        }
        else if (TryOtherPorts && Port != 25 && AttemptMailServer(MailServer, 25, true, out result.Response))
        {
            //Try port 25, with SSL.
            result.Found = true;
            result.UsedSSL = true;
            result.OriginalPortSuccess = false;
            result.FinalPort = 25;
            return result;
        }
        else if (TryOtherPorts && Port != 587 && AttemptMailServer(MailServer, 587, false, out result.Response))
        {
            //Try port 587, without SSL.
            result.Found = true;
            result.UsedSSL = false;
            result.OriginalPortSuccess = false;
            result.FinalPort = 587;
            return result;
        }
        else if (TryOtherPorts && Port != 587 && AttemptMailServer(MailServer, 587, true, out result.Response))
        {
            //Try port 587, with SSL.
            result.Found = true;
            result.UsedSSL = true;
            result.OriginalPortSuccess = false;
            result.FinalPort = 587;
            return result;
        }
        else
        {
            result.Found = false;
            result.OriginalPortSuccess = false;
            result.FinalPort = Port;
            return result;
        }
    }

    private static bool AttemptMailServer(string strMailServer, int intPort, bool blnSSL, out string strResponse)
    {
        try
        {
            if(!blnSSL)
            {
                //I'll try a basic SMTP HELO
                using (var client = new TcpClient())
                {
                    client.Connect(strMailServer, intPort);
                    using (var stream = client.GetStream())
                    {
                        using (var writer = new StreamWriter(stream))
                        using (var reader = new StreamReader(stream))
                        {
                            writer.WriteLine("EHLO " + strMailServer);
                            writer.Flush();
                            strResponse = reader.ReadLine();
                            if (strResponse == null)
                                throw new Exception("No Valid Connection");

                            stream.Close();
                            client.Close();
                            if (strResponse.StartsWith("220"))
                                return true;
                            else
                                return false;
                        }

                    }
                }
            }
            else
            {
                //I'll try with SSL
                using (var client = new TcpClient())
                {
                    client.Connect(strMailServer, intPort);
                    // 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(strMailServer);
                        using (var writer = new StreamWriter(sslStream))
                        using (var reader = new StreamReader(sslStream))
                        {
                            writer.WriteLine("EHLO " + strMailServer);
                            writer.Flush();

                            strResponse = reader.ReadLine();
                            if (strResponse == null)
                                throw new Exception("No Valid Connection");

                            stream.Close();
                            client.Close();
                            if (strResponse.StartsWith("220"))
                                return true;
                            else
                                return false;
                            // GMail responds with: 220 mx.google.com ESMTP
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            strResponse = ex.Message;
            return false;
        }
    }

}