读取所有输出时,Java套接字挂起

时间:2012-02-15 13:27:06

标签: java sockets

我有一个Java套接字连接到SMTP服务器以发送电子邮件,并使用BufferedReaderWriter来读取和写入套接字。我的问题是知道何时终止写入套接字后调用的while()循环;使用

while(bufferedreader.readLine() != null)

无效,就好像没有要从服务器读取的行BufferedReader只是挂起而不是返回null

4 个答案:

答案 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