我在本地Jetty下运行客户端和servlet。当我在客户端阅读邮件时,我会这样做:
in = new Scanner(conn.getInputStream());
StringBuffer messageBuffer = new StringBuffer();
while (in.hasNext()) {
messageBuffer.append(in.next()).append(" ");
}
我希望当没有来自servlet的数据时,它应该冻结在
while (in.hasNext())
相反,我最终得到了空的messageBuffer,我必须处理它并一次又一次地调用该方法,直到我收到消息。为什么会这样?如何让它在while语句处停止并等待有数据进入?
以下是url连接的启动方式(一次,在客户端构造函数中):
try {
url = new URL("http://localhost:8182/stream");
conn = (HttpURLConnection) url.openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException ioE) {
ioE.printStackTrace();
}
答案 0 :(得分:1)
:
next()和hasNext()方法及其原始类型的伴侣 方法(如nextInt()和hasNextInt())首先跳过任何输入 匹配分隔符模式,然后尝试返回下一个 令牌。 hasNext和next方法都可能阻止等待进一步 输入。 hasNext方法块是否与or无关 不会阻止其相关的下一个方法。
它说它可能会阻塞,但它不是api的一部分,它取决于你扫描的下划线实现。
无论如何,你需要通过以下方式实现等待:
while (!in.hasNext() && !stop){
sleep();
}
答案 1 :(得分:1)
javadoc指出Scanner.hasNext()
和Scanner.next()
可能阻止。这实际上取决于潜在的InputStream
。我个人不会使用Scanner
来读取套接字,如果是那样的话。
更合理的方法可能是使用由InputStreamReader
包裹的BufferedReader
。另外值得一提的是,除非您需要线程安全,否则您应该使用StringBuilder
而不是StringBuffer
。
BufferedReader br =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String input = null;
while ((input = br.readLine()) != null)
{
sb.append(input).append(" ");
}
请注意,这是使用readLine()
,可能会或可能不符合您的需求,具体取决于您收到的内容。它还假设连接的另一端在完成发送时将关闭。您可能希望使用其中一种read()
方法并进行相应的解析。
编辑以添加以下评论:这实际上是阻塞读取在Java中的工作方式。这是一个完整的例子:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class App
{
public static void main( String[] args ) throws MalformedURLException, IOException
{
URL url = new URL("http://www.google.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
BufferedReader br =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String input = null;
while ((input = br.readLine()) != null)
{
sb.append(input).append(" ");
}
System.out.println(sb.toString());
}
}
输出(此处为简洁起见,但它是整个页面):
<!doctype html><html itemscope="itemscope" itemtype="http://schema.org/WebPage"><head> ...
答案 2 :(得分:0)
编辑:
尝试使用for循环而不是while循环,其中范围将从0到(长度-1)。你必须使用while(in.hasNextLine())找到长度并在其中放入长度计数器。完成填充messageBuffer(使用.close())后,忘记关闭扫描程序。试一试吧。它应该工作。
答案 3 :(得分:0)
根据我的经验,我一直试图避免阻塞,因此避免在hasNext()中使用Scanner方法。
相反,我使用了InputStream。您在代码中使用的InputStream:
conn.getInputStream();
然后,您可以使用InputStream方法 available()查看是否有任何信息通过。
因此,对于您的代码,我建议:
InputStream inStream = conn.getInputStream();
in = new Scanner(inStream);
StringBuffer messageBuffer = new StringBuffer();
while (in.available() <= 0)
{
try{
Thread.sleep(100);
}
catch(InterruptedException e){}
}
messageBuffer.append(in.next()).append(" ");