0

我正在尝试为呼叫/响应 ping 建立超时。这是为了确定在自动连接序列中使用哪个 CommPort。当我发送CALL_SIGNALbyte[] 时,我希望得到“FU”作为回复。这就是我将如何确定哪个是我的设备。SSCCE 在下面(对不起,长度,但这缩短的版本)

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Timer;
import java.util.TimerTask;
import javax.comm.CommPortIdentifier;
import javax.comm.CommPort;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;

public class PingTest {
    public static final long PING_TIMEOUT = 1000; // in millis
    public static final byte[] CALL_SIGNAL = {70, 68, 73, 68};

    public boolean ping(CommPortIdentifier cpi)  {
        System.out.println("Pinging " + cpi.getName());
        CommPort port = null;
        InputStream input = null;
        OutputStream output = null;

        //Initialization test
        try {
            port = cpi.open("pingTest", 50);
            input = port.getInputStream();
            output = port.getOutputStream();
        } catch (PortInUseException ex) {
            if (cpi.getCurrentOwner().startsWith("pingTest")) {
                System.out.println("Port already owned by this application.");
                return true;
            }
            return false;
        } catch (Exception ex) {
            try {
            port.close();
            } catch (NullPointerException e) {
            }
            System.out.println("Failed initialization test.");
            System.err.println(ex);
            return false;
        }
        System.out.println("Passed initialization test."); 

        //Call and response test
        final Stop stop = new Stop();
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println("Stop timer triggered.");
                stop.shouldStop = true;
            }
        }, PING_TIMEOUT);
        try {
            System.out.println("Writing...");
            output.write(CALL_SIGNAL);
            System.out.println("Reading...");
            boolean waitForF = true;
            while (!stop.shouldStop && !stop.didPass) {
                if (waitForF) {
                    if ((byte) 'F' == input.read()) {
                        waitForF = false;
                    }
                } else {
                    System.out.println('F');
                    if ((byte) 'U' == input.read()) {
                        System.out.println('U');
                        stop.didPass = true;
                    } else {
                        System.out.println();
                        waitForF = true;
                    }
                }
            }
        } catch (IOException ex) {
            System.out.println("Failed I/O test.");
            return false;
        } finally {
            port.close();
        }

        if (stop.didPass) {
            System.out.println("Successful ping.");
            return true;
        }
        System.out.println("Failed call and response test.");
        return false;
    }

    public static void main(String[] args) {
        PingTest pinger = new PingTest();
        Enumeration<CommPortIdentifier> ports = CommPortIdentifier.getPortIdentifiers();
        boolean trigger = true;
        String name = null;
        while (trigger && ports.hasMoreElements) {
            CommPortIdentifier cpi = ports.nextElement();
            name = cpi.getName();
            trigger = !ping(cpi);
        }
        if (trigger) {
            System.out.println("Found it. It is " + name);
        } else {
            System.out.println("Not Found");
        }
    }
}

class Stop {
    boolean shouldStop = false;
    boolean didPass = false;
}

我的输出是:

Pinging COM1
Passed initialization test.
Writing...
Reading...
Stop timer triggered.

然后应用程序冻结。尝试用 a 停止 while 循环是否有问题Timer

4

2 回答 2

1

你的阅读被阻塞了。您需要使用超时

于 2012-06-04T20:49:51.043 回答
0

您在没有任何同步的情况下同时从不同线程访问共享状态(shouldStop和变量)。didPass如果您想确保阅读其他线程所写的内容,则应同步每次访问。

因此,要么添加方法来获取和设置这些变量,并使这些方法同步,或者,如果每个变量代表彼此不同的信息并且它们可以独立地写入和读取,则使这些变量易失。

第三种方法(仅在与 volatile 解决方案相同的条件下有效)是使用 AtomicBoolean 变量而不是布尔变量。

于 2012-06-04T20:46:47.320 回答