1

说我的要求是:用户在控制台(来自system.in)中输入一些东西或套接字接收一些东西,继续下一步。

所以我有一台扫描仪

Scanner sc = new Scanner(System.in);

有一个 udp 客户端。(不同的输入源)

DatagramSocket clientSocket = new DatagramSocket();

我的代码是

while (true) {
     if (sc.hasNext()) {
        String str = sc.next();
        proceed(str)
     } else { 
        clientSocket.receive(pack);
        proceed(pack)
     }
}

显然这段代码是行不通的。因为在检查 sc.hasNext() 时,java 正在等待用户在控制台中输入一些输入。目前我能做的是为 Udp 客户端打开一个线程。如果我改变顺序,

while (true) {
         clientSocket.receive(pack);
         if (not receive)  read from system.in
    }

这没有任何意义,因为 receive() 会一直等待 util 接收某些东西,所以它永远不会同时从 system.in 读取。

那么如何在不使用线程的情况下实现我的要求呢?

受@Andriy Kryvtsun 回答的启发,我做了一个快速测试 正如他所说,这在某种程度上使用了非阻塞读取,并不断让套接字超时,以模拟

        InputStream ins = System.in;
    byte buffer[] = new byte[512];
    BufferedReader reader = new BufferedReader(new InputStreamReader(ins));
    DatagramSocket clientSocket = new DatagramSocket();
    System.out.println("From buffer:" + clientSocket.getLocalPort());

    while (true) {
        try {
            if (ins.available() > 0) {
                String line = reader.readLine();
                System.out.println("Read:" + line);
            } else {

                DatagramPacket pack = new DatagramPacket(buffer,buffer.length);
                clientSocket.setSoTimeout(2000);
                clientSocket.receive(pack);
                System.out.println("Receive: " + new String(pack.getData()));
            }
        } catch (IOException e1) {

        }
    }
4

1 回答 1

2

InputStream#available()如果在使用阻塞调用之前准备好读取内容,请使用解除阻塞方法调用来获取信息Scanner#hasNext()

您也可以DatagramSocket#setSoTimeout(int timeout)在调用阻塞receive(DatagramPacket p)方法之前调用。因此,您可以在模拟畅通读取的周期receive后打破方法内部的无限等待。timeout

于 2016-03-24T17:21:36.457 回答