【问题标题】:Why JavaMail connection timeout is too long为什么 JavaMail 连接超时时间过长
【发布时间】:2013-09-23 23:13:15
【问题描述】:

在我的应用程序中,我连接到服务器以验证用户身份。这是代码:

try {
        Properties prop = new Properties();
        prop.put("mail.smtp.starttls.enable","true");
        prop.put("mail.smtp.auth", "true");
        prop.put("mail.smtp.connectiontimeout", 1000);


        Session session = Session.getInstance(prop, null);
        Transport transport = session.getTransport("smtp");
        transport.connect("mion.elka.pw.edu.pl", 587, registerLog, registerPass);
        transport.close();
        return true;
    } catch (NoSuchProviderException ex) {
        Logger.getLogger(RegisterController.class.getName()).log(Level.SEVERE, null, ex);
        return false;
    } catch(AuthenticationFailedException ex) {
        Logger.getLogger(RegisterController.class.getName()).log(Level.SEVERE, null, ex);
        return false;
    } catch (MessagingException ex) {
        Logger.getLogger(RegisterController.class.getName()).log(Level.SEVERE, null, ex);
        return false;
    }

我将连接超时设置为 1000 毫秒 = 1 秒,但它被忽略了。当我调试并设置错误的用户名和密码时,我会抓住

javax.mail.MessagingException: java.net.SocketTimeoutException: Read timed out

不是在 1000 毫秒之后,而是在 5000*60 毫秒 = 5 分钟之后

怎么了?我怎样才能减少超时?

【问题讨论】:

  • 连接超时和读取超时是两个不同的东西,不是一回事。您已经设置了一个并体验了另一个。
  • 那么在这种情况下如何设置读取超时?
  • 未启用 starttls 时是否仍会出现长时间超时?我认为 Java Mail 中可能存在一个错误,即启用 starttls 时超时会变得很长。
  • starttls 是什么意思?

标签: java jakarta-mail connection-timeout


【解决方案1】:

你也可以设置 Socket I/O 超时吗?当它连接成功但无法从服务器读取数据时,它会继续等待。

prop.put("mail.smtp.timeout", 1000);

读取超时表示您已连接但无法从服务器读取数据。

【讨论】:

  • 当我将 prop.put("mail.smtp.connectiontimeout", 1000); 替换为 prop.put("mail.smtp.timeout", 1000); 到我的代码时,什么也没发生。我必须等待 5 分钟 再次 才能赶上 javax.mail.MessagingException: java.net.SocketTimeoutException: Read timed out
  • 您使用的是什么版本的 JavaMail?如果开启 Session 调试,调试输出会显示什么?
  • JavaMail 1.4 版本,
  • 如果我打开调试,它会在transport.connect("mion.elka.pw.edu.pl", 587, registerLog, registerPass); 停止,5 分钟后我会:java.net.SocketTimeoutException: Read timed out
  • 您使用的是相当旧的 JavaMail 版本。在设置超时属性时尝试使用字符串而不是整数。旧版本的 JavaMail 只能正确处理字符串。
【解决方案2】:

由于您使用的是 SSL,您可以尝试配置 smtps 命名空间,而不是 smtp

prop.put("mail.smtps.timeout", 1000);
prop.put("mail.smtps.connectiontimeout", 1000);

顺便说一句:属性中的超时值可以作为intString 传递。 JavaMail 将正确处理它们(至少 v1.5+)。

【讨论】:

  • smtp、smtps我都试过了。没有任何效果,大约需要 7 秒。 javax-mail的版本是1.6.2
【解决方案3】:

我遇到了同样的问题。它使用字符串而不是整数。

prop.put("mail.smtp.timeout", "1000");    
prop.put("mail.smtp.connectiontimeout", "1000");    

【讨论】:

  • 根据the JavaDocs:SMTP协议提供者支持以下属性,可以在JavaMailSession对象中设置。 属性总是设置为字符串; Type 列描述了字符串是如何被解释的。
【解决方案4】:

不,只是因为 value 必须是字符串“1000”而不是整数 1000

【讨论】:

  • 能否请您提供更具体的答案?
  • @robbyone 看看我在 shamimz 的回答下面的评论。在 2013 年 9 月 24 日 22:07,我写道:“不幸的是,将值更改为字符串而不是整数并没有帮助,我仍然需要等待 5 分钟。您认为更改为较新版本可以解决问题吗?”
【解决方案5】:

ma​​il.smtp.connectiontimeout
类型:int
描述:套接字连接超时值,以毫秒为单位。此超时由 java.net.Socket 实现。默认为无限超时。

ma​​il.smtp.timeout 类型:int
描述:套接字读取超时值,以毫秒为单位。此超时由 java.net.Socket 实现。默认为无限超时。

ma​​il.smtp.writetimeout 类型:int
描述:套接字写入超时值,以毫秒为单位。这个超时是通过对每个连接使用 java.util.concurrent.ScheduledExecutorService 来实现的,如果超时到期,它会调度一个线程来关闭套接字。因此,使用此超时的开销是每个连接一个线程。默认为无限超时。

【讨论】:

    【解决方案6】:

    我通过更改为最新版本的 JavaMail(JavaMail 1.5)解决了我的问题。我在那里写了:http://openejb.979440.n4.nabble.com/Which-version-of-JavaMail-td4665285.html

    感谢大家的帮助,特别是比尔香农:)

    【讨论】:

    • 很高兴知道解决方案,因为该链接不再可用。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多