Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SmtpClient can't send; Thunderbird can

This should be pretty routine, right?

public static SmtpClient GetSmtpClient()
{
    var client = new SmtpClient
    {
        Host = _smtpServer,
        UseDefaultCredentials = false,
        Credentials = new NetworkCredential(_smtpUsername, _smtpPassword),
        Port = _smtpPort, // port 25
        EnableSsl = _smtpSsl // false
    };
    return client;
}
...
var m = new MailMessage 
{
    // contents of mail message
}
using (var server = GetSmtpClient())
{
    server.Send(m);
}

But server.Send() is throwing an SmtpException:

Failure sending mail. ---> System.IO.IOException: Unable to read data from the transport connection: net_io_connectionclosed

Something wrong with my credentials? IP block on the SMTP server? Maybe my ISP blocking outgoing requests to port 25? I downloaded and installed Thunderbird on the same machine as my debug environment, and set up identical SMTP credentials there, and it works perfectly.

So why does it work in Thunderbird, but not in my code?

UPDATE: Following up on @tzachs's suggestion, I downloaded Wireshark and found that the transaction progress is identical, up to a point.

Thunderbird:

TCP 62  25 → 50924 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1360 SACK_PERM=1
SMTP    143 S: 220 smtp.somedomain.com ESMTP Sendmail 8.13.8/8.13.8; Sat, 5 Dec 2015 15:46:22 -0500
TCP 54  25 → 50924 [ACK] Seq=90 Ack=18 Win=5840 Len=0
SMTP    289 S: 250 smtp.somedomain.com Hello my-computer.myisp.com [x.x.60.61], pleased to meet you | 250 ENHANCEDSTATUSCODES | 250 PIPELINING | 250 8BITMIME | 250 SIZE | 250 DSN | 250 ETRN | 250 AUTH LOGIN PLAIN | 250 DELIVERBY | 250 HELP
SMTP    82  S: 235 2.0.0 OK Authenticated
etc.

SmtpClient:

TCP 62  25 → 50889 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1360 SACK_PERM=1
SMTP    143 S: 220 smtp.somedomain.com ESMTP Sendmail 8.13.8/8.13.8; Sat, 5 Dec 2015 15:45:08 -0500
TCP 54  25 → 50889 [ACK] Seq=90 Ack=21 Win=5840 Len=0
SMTP    289 S: 250 smtp.somedomain.com Hello my-computer.myisp.com [x.x.60.61], pleased to meet you | 250 ENHANCEDSTATUSCODES | 250 PIPELINING | 250 8BITMIME | 250 SIZE | 250 DSN | 250 ETRN | 250 AUTH LOGIN PLAIN | 250 DELIVERBY | 250 HELP
TCP 54  25 → 50889 [FIN, ACK] Seq=325 Ack=62 Win=5840 Len=0
TCP 54  25 → 50889 [ACK] Seq=326 Ack=63 Win=5840 Len=0

Notice that after the "pleased to meet you" line in the SmtpClient trace, there's nothing about authentication. Not "accepted", not "failed" - nothing. Just terminates the connection.

Does that shed any light?

ANOTHER UPDATE: The Smtp server is running SendMail, FWIW. The error is specific to this particular Smtp host; when I point at different servers, the code works fine.

like image 645
Shaul Behr Avatar asked Dec 04 '15 13:12

Shaul Behr


1 Answers

I did have my share of issues working with different SMTP servers. On my experience, the default .net smtpclient API sometimes doesn't tell you what is really happening (to be fair it could be a side effect of simplifying things for us). What helped me in the past, specially on the troubleshooting phase is the use of a .Net SMTP API that allows me to debug it up to the rcpt commands and give me richer exception information.

For that i recommend you to download the source code of this project and debug their SMTP examples : MailSystem.Net There is a windows forms project named ActiveUp.Net.Samples, just build and execute it and you are good to go on minutes.

If you prefer to use it programmatically, its quite similar than the .net smtpclient (and it does have an overload to pass credentials):

        ActiveUp.Net.Mail.Message message = new ActiveUp.Net.Mail.Message();

        // We assign the sender email
        message.From.Email = this.fromEmailTextbox.Text;

        // We assign the recipient email
        message.To.Add(this.toEmailTextbox.Text);

        // We assign the subject
        message.Subject = this.subjectTextbox.Text;

        // We assign the body text
        message.BodyText.Text = this.bodyTextTextbox.Text;

        // We send the email using the specified SMTP server
        this.AddLogEntry("Sending message.");

        try
        {
            SmtpClient.Send(message, this.smtpServerAddressTextbox.Text);

            this.AddLogEntry("Message sent successfully.");
        }
        catch (SmtpException ex)
        {
            this.AddLogEntry(string.Format("Smtp Error: {0}", ex.Message));
        }
        catch (Exception ex)
        {
            this.AddLogEntry(string.Format("Failed: {0}", ex.Message));
        }

Hope it helps.

like image 84
Jhonatan P Avatar answered Nov 15 '22 14:11

Jhonatan P