java扫描程序阻止.next()时它不应该

时间:2015-10-16 20:40:38

标签: java network-programming java.util.scanner inputstream outputstream

我正在创建一个简单的服务器/客户端应用程序。服务器将socket.getInputStream()包装在Scanner中。客户端从System.in获取用户输入,并使用PrintWriter将其发送到服务器。服务器将scanner.hasNext()评估为true,但它会在以下scanner.next()调用时阻止。根据javadocs:

  

即使之前的hasNext()调用返回true,此方法也可能在等待输入扫描时阻塞。

好吧......这有什么用呢? 编辑:值得注意的是,当客户端终止时,服务器现在继续调用scanner.next()。加分问题:客户端将PrintWriter autoFlush参数设置为true,但我需要在每次调用.write()后刷新。为什么?这是我的代码的MCV:

import java.io.IOException;
import java.net.ServerSocket;
import java.util.Scanner;

public class MCVServer {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(1337);
        Scanner fromClient = new Scanner(server.accept().getInputStream());
        while (fromClient.hasNext()) {
            System.out.println("server heard something: ");
            System.out.println(fromClient.next());
        }
    }
}
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class MCVClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket socket = new Socket("localhost", 1337);
        Scanner input = new Scanner(System.in);
        PrintWriter output = new PrintWriter(socket.getOutputStream(), true);

        while(true) {
            output.write(input.next());
            output.flush();
        }
    }
}

3 个答案:

答案 0 :(得分:1)

  1. scan.hasNext()读取,直到可以检测到下一个令牌的开头。这并不意味着已经读取或接收了整个令牌。但是scanner.next()必须读取所有令牌;因此它可能会阻止。

  2. Autoflush仅在调用方法println,printf或format后生效。

答案 1 :(得分:1)

方法next()和hasNext()的行为按预期工作。方法hasNext只有在到达流的末尾后才返回false。如果方法仍未到达流的末尾或等待输入,则next()方法将被阻止。

奖金问题也很简单。根据PrintWriter类的文档:

  

与PrintStream类不同,如果启用了自动刷新,则只有在调用println,printf或format方法之一时才会执行,而不是每当输出换行符时。这些方法使用平台自己的行分隔符概念而不是换行符。

因此,为了使用autoflushing,你需要用println替换write方法:

while (true) {
        output.println(input.next());
}

答案 2 :(得分:0)

使用NextLine()而不是Next()