我有一个Java套接字连接到SMTP服务器以发送电子邮件,并使用BufferedReader
和Writer
来读取和写入套接字。我的问题是知道何时终止写入套接字后调用的while()
循环;使用
while(bufferedreader.readLine() != null)
无效,就好像没有要从服务器读取的行BufferedReader
只是挂起而不是返回null
。
答案 0 :(得分:2)
从套接字读取数据时不要使用readLine()
,因为readLine()
假定传入流是文本文件,其中包含行结尾。这可能不是这种情况,它会无限期地阻塞readLine()
,因为即使传入的流已经结束,也没有行结束。
答案 1 :(得分:0)
您需要解析流中的SMTP条消息,以确定何时停止。例如,您需要向服务器发送QUIT
消息以指示您已完成,然后捕获221 Bye
。
答案 2 :(得分:0)
我强烈建议不要重新发明轮子并使用SMTPClient项目中的Apache Commons Net。
除非你正在做一些研究/教育工作。
答案 3 :(得分:0)
你不能使用“while(bufferedreader.readLine()!= null)”,因为它的作用是从套接字的每一行读取,并挂起直到发布新内容。
除了“QUIT”命令外,它不起作用,因为对于与SMTP服务器对话的其他阶段,您只需要读取几行,然后发送另一个命令等,等等
根据您运行的smtp命令的类型,您会得到不同的答案。您必须仔细阅读SMTP RFC(基于2821 - http://www.ietf.org/rfc/rfc2821.txt)以了解底层协议。
基本上,您将发送的大多数命令都会收到带有结果代码的单行答案。此代码指示要执行的操作(读取更多行,或跳到下一个命令)。
例如:通过发送'HELO myserver',你会得到'250 xxx'的答案(或者它是失败的!)。
所以你只需阅读1行。
通过发送'EHLO myserver',您会期望更多行,不记得停止条件。
等等等......例如,在我的本地EXIM上,我有这些结果:
首先,从服务器读取1行,检查220
220 jm.localdomain ESMTP Exim 4.72 Wed, 15 Feb 2012 13:52:36 +0100
然后发送:
HELO localhost
阅读并检查250:
250 jm.localdomain Hello me [127.0.0.1]
等等
MAIL FROM: me@yahoo.com
250 OK
RCPT TO: everybody@yahoo.com
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
Subject: how are you?
bla
bla
bla
.
250 OK id=1RxePi-00074k-Nv
QUIT
221 jm.localdomain closing connection