问题
I can't seem to find the cause for this problem.
Sometimes I get SmtpException
"4.7.0 timeout waiting for client input" being thrown on using the following c# code for .net-4.0:
using System;
using System.Net.Mail;
namespace SendMail
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
string html = "<h1>TEST</h1>";
using (MailMessage mail = new MailMessage("sender@domain.com", "receiver@domain.com"))
{
mail.Subject = "Test";
mail.IsBodyHtml = true;
mail.Body = html;
using (SmtpClient client = new SmtpClient("<internal ip address>"))
{
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("<user name>", "<password>");
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Send(mail);
}
}
}
}
}
}
It usually crashes at the second attempt (i == 1).
I am aware I should create a single SmtpClient
instance and reuse it in the loop but for the purpose of demonstration and in order to be as close as possible to the real code it has to be this way. While the above isn't quite like my production code it does suffer from the same random problem. I figured that if I could solve the problem with this code then I'd know what to do with my actual code, given that it really is a coding issue to begin with. I'm suspecting an obscure server configuration issue but I'm out of ideas on what it could possibly be.
Odd thing: despite being a timeout issue, the exception is thrown very quickly; there's no delay that would suggest an actual timing out problem.
The mail server is MS exchange-server-2007 running on windows-server-2008 SP2. There's no additional SMTP settings specified in app.config file.
I tried to put the code in a Do...While
loop that tries five times to send the email back after putting the thread to sleep for one second. Unfortunately that doesn't help: when it fails, it will also fail at the very next attempts.
I also tried using Thread.Sleep(<delay>)
before every calls to client.Send(message)
but it made no appearant difference.
Our network admin is adamant on the network running without any issues (no packet drops caused by bad MTU setting or anything like that). He backs this up with the fact that there's only my code that seems to have problems (and he's right) and that it does not only happen on a segment of the network (also right).
It's unlikely that the firewall would be causing this either, as every mail my app sends is using internal addresses.
Anybody has a clue here? It would be much appreciated.
UPDATE:
I seem to be able to reproduce the problem every time when using default credentials instead:
using (SmtpClient client = new SmtpClient("<internal ip address>"))
{
client.UseDefaultCredentials = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Send(mail);
}
UPDATE 2:
Nope. Not every time. Everything now works again (until next time).
I really can't put my finger on it.
UPDATE 3:
Interesting new development today: I attempted to create a new account inside MS Outlook with the same address I use with Exchange. Only this time instead of adding it as an MS Exchange address I tried setting it up as a POP3/SMTP account. Here is what happened upon testing the connection:
It's in french but look at the last line: it is the exact same error message I got with my code. This is a clear indication to me that the issue is not within my code.
Of course, this also means that this whole thread shouldn't be on SO. Still, I hope this extra test can help fellow developers out there who are struggling with a similar issue.
回答1:
This definitely sounds like a server or network issue. Reference this serverfault post for instance: https://serverfault.com/questions/344684/exchange-2007-email-error-451-4-7-0-timeout-waiting-for-client-input
It could be a firewall problem if there is a firewall between your machine and the exchange server. A firewall blocks ports between ip addresses, it doesn't matter where the email is going at all. Firewalls are the bane of my programming existence, so definitely ask your net admin if there is a firewall between the servers and have him check if it is working.
It could also be something like a bad NIC (network card) on the server or even a bad cable. Yes, your network admin said the network is rock solid... but never trust network admins. ;)
It could also be a problem with YOUR network card, network settings or ethernet cable, actually.
Have you tried running this from different computers?
回答2:
You can fire if off async like by changing your code as follows. You will need to check the AggregateException to see if something bad happened on any of the executing threads.
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
string html = "<h1>TEST</h1>";
Task.Factory.StartNew(() =>
{
using (MailMessage mail = new MailMessage("sender@domain.com", "receiver@domain.com"))
{
mail.Subject = "Test";
mail.IsBodyHtml = true;
mail.Body = html;
using (SmtpClient client = new SmtpClient("<internal ip address>"))
{
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("<user name>", "<password>");
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Send(mail);
}
}
}).ContinueWith(aex => {
if (aex.Exception != null)
{
//add some logic to deal with the exception
}
});
}
}
回答3:
it is better to define SmtpClient before the loop, same problem happened with me and this solved it.
using System;
using System.Net.Mail;
namespace SendMail
{
class Program
{
SmtpClient client = new SmtpClient("<internal ip address>");
static void Main(string[] args)
{
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("<user name>", "<password>");
//client.EnableSsl = true;
//client.Port = 25;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
for (int i = 0; i < 100; i++)
{
string html = "<h1>TEST</h1>";
using (MailMessage mail = new MailMessage("sender@domain.com", "receiver@domain.com"))
{
mail.Subject = "Test";
mail.IsBodyHtml = true;
mail.Body = html;
client.Send(mail);
}
}
}
}
}
回答4:
I'm fairly new to this messaging issue. I have currently been working on a messaging application and occasionally this exception is thrown into the system. So far the answers I have picked up on the internet point out that this is an error in the email sender's authentication. Perhaps the limitation of daily submissions and the hourly send limit may inhibit SMTP server authentication of the email. Example, in case smtps.bol.com.br has a limit of 50 emails per hour, having to have a 60 minute interval to send a new batch of messages. I have done my tests here and I do not have a conclusive answer, but I believe that maybe the way is this. If they find the definitive solution, do not forget to post.
回答5:
I was getting similar error couple of years back on Amazon Aws server. It seems my security company "AllCovered.com" had to do a exception to my server ip address to allow send smtp emails.
I do get this error if anytime a new server created is forgotten to be put in exception.
来源:https://stackoverflow.com/questions/24956306/smtpclient-send-randomly-causes-smtpexception-4-7-0-timeout-waiting-for-client-i