I've summed up several messages that have been sent back, leakage explanation: 1. network; 2 firewall; 3. Server self-protection, such as preventing mass-mailing or spam, I think the third explanation is a bit more plausible, and the following articles provide remedial measures for these problems.
Company mailbox is currently using Zimbra, the mail server is not very stable at present, often appear again, leakage problems. After testing, each 100 messages can only successfully send about 98, the following is the test data:
Test Case 1:100, total time approximately: 16min; 97, 3 failure, 3 error messages are: Javax.mail.MessagingException:Could not connect to SMTP host
Test Case 2:100, total time about: 16min, 100, failed 2 times, error ibid. Plus failure to repeat the mechanism, after the failure to wait for 10s, the maximum 3 times;
Test Case 3: Each send a, stay 10s, total time 32min, real 100, 1 failures, errors, the same as use Case 2.
Regarding the messagingexception question, may refer to:
Javax.mail.MessagingException:Could not connect to SMTP host
In response to this problem, I added a message to the post,
if (sendhtmlmail_ (mail)) {return
true;
} else{
int i = 0;
Include group mail, failure not to repeat
boolean isneedre = isneedre (mail);
while (!sendhtmlmail_ (mail) && isneedre && i <) {
try {
i++;
Thread.Sleep (1000*60);
} catch (Interruptedexception e) {
logger.error ("Resend Mail Error", e);
}
}
return true;
}
However, this mechanism creates a new problem, because the mail server is not stable, the message will be sent to the mail recipient only once, and the recipient of the same message (including CC, BCC) may receive a partial message, part of the message is not received.
For the above problems, we will remove the mechanism, only for illegal mail (that is, the server does not exist on the e-mail address) to remove, remove and then send. For other reasons, the message sent failed to resend (the issue will be reflected through the mail server shipping department to the manufacturer).
Here is the logic to determine whether a message is legitimate:
1.SMTP is working in two cases: one is the transfer of e-mail from the client to the server, and the other is transferring from one server to another
2.SMTP is a request/response protocol in which commands and responses are based on ASCII text and end with CR and LF. The response includes a three-bit numeric code that represents the return status
3.SMTP listens for connection request at TCP protocol Port 25th
4. Connection and send process
The SMTP protocol says it's not complicated, it's easy to say if you know the socket. But now we're just using the first one to say, from the client to the server, when we send a message to a server, the mail server first verifies that the mailing address really exists on this server.
5 Steps for the operation are as follows:
25 port to connect to the server (if there is no mail service, even Bailian)
Send Helo Greetings
Send mail from command, if return 250 indicates correct can, connect this server, otherwise the server needs sender authentication.
Send RCPT TO command, if return 250 indicates then email exists
Send quit command, exit connection
Based on the above logic, we encapsulate the mail server to form a socket, send a command, and determine whether the email address is legitimate according to the return value:
The specific code is as follows:
Import java.io.*;
Import java.net.*;
Import java.util.*;
Import javax.naming.*;
Import javax.naming.directory.*;
public class Smtpmxlookup {private static int hear (BufferedReader in) throws IOException {String line = null;
int res = 0;
while (line = In.readline ())!= null) {String PFX = line.substring (0, 3);
try {res = Integer.parseint (PFX);
catch (Exception ex) {res =-1;
} if (Line.charat (3)!= '-') break;
return res;
private static void Say (BufferedWriter wr, String text) throws IOException {wr.write (text + "\ r \ n");
Wr.flush ();
Return private static ArrayList getmx (String hostName) throws Namingexception {//Perform a DNS lookup for MX Rec
Ords in the domain Hashtable env = new Hashtable ();
Env.put ("Java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
DirContext ictx = new InitialDirContext (env); Attributes Attrs= Ictx.getattributes (HostName, new string[] {"MX"});
Attribute attr = Attrs.get ("MX"); If we don ' t have an MX record, try the machine itself if ((attr = = null) | | (attr.size () = 0))
{attrs = Ictx.getattributes (HostName, new string[] {"A"});
attr = Attrs.get ("A");
if (attr = null) throw new Namingexception ("No Match for Name" + HostName + ""); }//huzzah! We have machines to try. Return them as a array list//Note:we SHOULD take the preference to is absolutely//correct.
This is the left as a exercise for anyone who cares.
ArrayList res = new ArrayList ();
Namingenumeration en = Attr.getall ();
while (En.hasmore ()) {String mailhost;
string x = (string) en.next ();
String f[] = X.split ("");
The Fix ************* if (f.length = = 1) mailhost = f[0];
else if (F[1].endswith (".")) Mailhost = f[1].substring (0, F[1].length ()- 1));
else mailhost = f[1];
The Fix ************* res.add (mailhost);
return res; public static Boolean isaddressvalid (String address) {//Find the separator for the domain name int pos = A
Ddress.indexof (' @ ');
If the address does isn't contain an ' @ ', it's not valid if (pos = 1) return false;
Isolate the Domain/machine name and get a list of mail exchangers String domain = address.substring (++pos);
ArrayList mxlist = null;
try {mxlist = getmx (domain);
catch (Namingexception ex) {return false; }//Just because we can send mail to the domain, doesn ' t mean this//address is valid, but if we can ' t, it ' s
A sure sign that it isn ' t if (mxlist.size () = = 0) return false; Now, does the SMTP validation, try each mail exchanger until we/a positive acceptance. It *may* be possible for one MX to allow//a message [store and forwarder for example] and another [like//The actual mail server] to reject it.
This is why we really ought/to take the preference into account.
for (int mx = 0; mx < mxlist.size (); mx++) {Boolean valid = false;
try {int res;
Socket Skt = new Socket ((String) mxlist.get (MX), 25);
BufferedReader rdr = new BufferedReader (New InputStreamReader (Skt.getinputstream ()));
BufferedWriter WTR = new BufferedWriter (New OutputStreamWriter (Skt.getoutputstream ()));
res = hear (RDR);
if (res!=) throw new Exception ("Invalid header");
Say (WTR, "EHLO rgagnon.com");
res = hear (RDR);
if (res!=) throw new Exception ("Not ESMTP");
Validate the sender address say (WTR, "MAIL from: <tim@orbaker.com>");
res = hear (RDR);
if (res!=) throw new Exception ("Sender rejected"); Say (WTR, "RCPT to: <" + address + ">");
res = hear (RDR); Be polite say (WTR, "RSET");
Hear (RDR); Say (WTR, "QUIT");
Hear (RDR);
if (res!=) throw new Exception ("Address isn't valid!");
valid = true;
Rdr.close ();
Wtr.close ();
Skt.close ();
The catch (Exception ex) {//Do nothing but try next host ex.printstacktrace ();
finally {if (valid) return true;
return false; public static void Main (string args[]) {string testdata[] = {"Real@rgagnon.com", "You@acquisto.net" , "Fail.me@nowhere.spam",//Invalid domain Name "arkham@bigmeanogre.net",//Invalid address "nosuchaddres
S@yahoo.com "//Failure of this method};
for (int ctr = 0; Ctr < testdata.length; ctr++) {System.out.println (testdata[Ctr] + ' is valid? "+
Isaddressvalid (testdata[Ctr]));
} return; }
}
The above is the logic to determine if the email address is legitimate, and if the email address is illegal, remove the mailing address from the recipient list.
private static string[] Removeinvalidateaddress (string[] addresses, String mailfrom) {arraylist<string>
validateaddresses = new arraylist<string> ();
String normaladdress = null;
int code;
Smtptransport Smpttrans = null;
if (Stringutils.isempty (mailfrom) | | | null = = addresses) {return new string[0];
String sendcmd = "MAIL from:" + normalizeaddress (mailfrom);
try {Smpttrans = (smtptransport) sendsession.gettransport ("SMTP");
Smpttrans.connect ();
Code = Smpttrans.simplecommand (Sendcmd);
If (Code!= && Code!= 251) {logger.error ("Send from invalidate" + mailfrom);
else {for (String address:addresses) {normaladdress = normalizeaddress (address);
String cmd = "RCPT to:" + normaladdress;
Code = smpttrans.simplecommand (cmd);
if (code = = | | | code = = 251) {Validateaddresses.add (address); }
(Messagingexception e) {logger.error ("Validate mail address error.
Send from "+ Mailfrom, E);
String[] result = Validateaddresses.toarray (new String[validateaddresses.size ()));
return result; private static string normalizeaddress (String addr) {if (!addr.startswith ("<")) && (!addr.
EndsWith (">")) return "<" + addr + ">";
else return addr;
}
The above is the entire content of this article, I hope you can understand, to help everyone.