在 class 和 运行 线程之间传递数据

Passing data between class and running thread

使用 stockoverflow 中的代码示例,我制作了一个 class 以通过 TCP/IP 接收数据。 Class 下面的代码。它工作正常,我确实从其他 PC 接收数据。 recPositions 地图构建正确。传输完成后,我可以使用 getRecPositions()

显示我收到的所有数据

此线程在构建简单 HMI 屏幕的其他 class 中启动。 线程运行并显示从其他 PC 接收到的数据。 问题是我想在 MainWindow class (HMI) 中访问相同的数据 但它总是显示没有收到任何东西。 Class MainWindow 下面(不是全部,因为有很多无用的按钮等等) 在最底部,我有一个按钮,应该显示记录了多少位置(地图中的元素),但它始终显示 0。 来自按钮更新的代码片段。

System.out.println(dataServer.getRecPositions().size())

所以在某些时候我做错了什么。 线程启动并运行,我可以看到传入的位置。在我收到 "EOT" 后的某个时候,我显示了存储在地图中的收到位置。但是当我试图在 main window 中显示 Map 的大小时,它总是显示 0。

/*
 * Simple data server for receiving string data from IIWA robot
 */
public class SimpleDataServer implements Runnable {

    Map<Integer, String> recPositions = new HashMap<>();
    Server1Connection oneconnection;
    ServerSocket echoServer = null;
    Socket clientSocket = null;
    int port;
    boolean reset = false;

    public SimpleDataServer( int port ) {
        this.port = port;
    }

    public void stopServer() {
        System.out.println( "Simple data server stopped" );
    }

    public void startServer() {
        // Try to open a server socket on the given port
        // Note that we can't choose a port less than 1024 if we are not
        // privileged users (root)

        try {
            echoServer = new ServerSocket(port);
        }
        catch (IOException e) {
            System.out.println(e);
        }   

        System.out.println( "Waiting for connections. Only one connection is allowed." );

        // Create a socket object from the ServerSocket to listen and accept connections.
        // Use Server1Connection to process the connection.

        while ( true ) {
            try {
                clientSocket = echoServer.accept();
                oneconnection = new Server1Connection(clientSocket, this); 
                oneconnection.run();
                if(isReset()) {
                    setReset(false);
                    System.out.println("Recording finished");
                    System.out.println("DEBUG:" + this.getRecPositions().size() + " positions recorded: " + this.getRecPositions());
                }
            }   
            catch (IOException e) {
                System.out.println(e);
            }
        }
    }

    @Override
    public void run() {
        int port = this.port;
        SimpleDataServer server = new SimpleDataServer( port );
        server.startServer();
    }

    public Map<Integer, String> getRecPositions() {
        return recPositions;
    }

    public void setRecPositions(Map<Integer, String> recPositions) {
        this.recPositions = recPositions;
    }

    public boolean isReset() {
        return reset;
    }

    public void setReset(boolean reset) {
        this.reset = reset;
    }

}

class Server1Connection {
    BufferedReader is;
    PrintStream os;
    Socket clientSocket;
    SimpleDataServer server;

    public Server1Connection(Socket clientSocket, SimpleDataServer server) {
        this.clientSocket = clientSocket;
        this.server = server;
        System.out.println( "Connection established with: " + clientSocket );
        try {
            is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            os = new PrintStream(clientSocket.getOutputStream());
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public Map<Integer, String> getPositions() {
        return server.getRecPositions();
    }

    public void run() {
        String line;    //whole line recevied
        String segment = null;  //single segment from line using comma delimiter
        List<String> stringsList;
        try {
            boolean serverStop = false;
            //server runs here
            while (true) 
            {
                line = is.readLine();
                System.out.println( "DEBUG Server Received: " + line );
                //check is string is not empty
                if (line.equals(null)) {
                    System.err.println("Empty String received");
                    break;
                }           
                stringsList = new ArrayList<String>(Arrays.asList(line.split(";")));
                if (!stringsList.isEmpty()) {
                    stringsList.set(0, stringsList.get(0).replaceAll("\s+",""));
                    stringsList.set((stringsList.size()-1), stringsList.get(stringsList.size()-1).replaceAll("\s+",""));

                    String lastSegment = stringsList.get((stringsList.size()-1));
                    if (lastSegment.equals("ETX") || lastSegment.equals("EOT")) {
                        switch (stringsList.get(0)) {
                        case "MSG":
                            stringsList.remove(0);
                            stringsList.remove(stringsList.size()-1);
                            System.out.println("Message: " + stringsList.toString());
                            break;
                        case "POS":
//                          for (String blah : stringsList) {
//                              System.out.println("DEBUG" + blah);
//                          }
                            iiwaPosfromString iiwaPos = new iiwaPosfromString(stringsList.get(1), stringsList.get(2));
                            System.out.println("DEBUG Position number: " + iiwaPos.posNum + " ; "  + iiwaPos.toString());
                            if (iiwaPos.getPosNum() > 0) {
                                server.getRecPositions().put(iiwaPos.getPosNum(), iiwaPos.toString());
                            }
                            break;

                        case "EOT":
                        case "EXT":
                            //ignore handled later
                            break;
                        default:
                            System.err.println("Ausgebombt!");
                            break;
                        }

                    }
                    //ETX End Of Text - dump data to screen - close current connection
                    if(lastSegment.equals("ETX")) {
                        System.out.println("End of Text received");
                        break;
                    }
                    //EOT End Of Transmission - shuts down server
                    if(lastSegment.equals("EOT")) {
                        System.out.println("End of Transmission received");
                        serverStop = true;
                        server.setReset(true);
                        break;
                    }
                    System.err.println("No correct end string!");
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;

                } else {
                    System.out.println("Empty String received");
                    break;
                }
            }

            System.out.println( "Connection closed." );
            is.close();
            os.close();
            clientSocket.close();

            if ( serverStop ) server.stopServer();
        } catch (IOException e) {
            System.out.println(e);
        }
    }


    public class iiwaPosfromString {
        private double posX;
        private double posY;
        private double posZ;
        private double posA;
        private double posB;
        private double posC;
        private int posNum;

        public iiwaPosfromString(String posNum, String posString) {
            List <String>stringsList = new ArrayList<String>(Arrays.asList(posString.split(" ")));
            for (int i = 0; i < stringsList.size(); i++) {
                String newElement = stringsList.get(i);
                newElement = newElement.replaceAll("[^\d.]", "");
                stringsList.set(i, newElement);
            }
            this.setPosNum(Integer.parseInt(posNum));
            this.setPosX(Double.parseDouble(stringsList.get(1)));
            this.setPosY(Double.parseDouble(stringsList.get(2)));
            this.setPosZ(Double.parseDouble(stringsList.get(3)));
            //this is stupid and don't do that
            //from right to left, string to double, change radians to degrees, format to two decimals(string), string to double again
            this.setPosA(Double.parseDouble(String.format("%.2f",(Math.toDegrees(Double.parseDouble(stringsList.get(4)))))));
            this.setPosB(Double.parseDouble(String.format("%.2f",(Math.toDegrees(Double.parseDouble(stringsList.get(4)))))));
            this.setPosC(Double.parseDouble(String.format("%.2f",(Math.toDegrees(Double.parseDouble(stringsList.get(4)))))));
        }

        public double getPosX() {
            return posX;
        }

        public void setPosX(double posX) {
            this.posX = posX;
        }

        public double getPosY() {
            return posY;
        }

        public void setPosY(double posY) {
            this.posY = posY;
        }

        public double getPosZ() {
            return posZ;
        }

        public void setPosZ(double posZ) {
            this.posZ = posZ;
        }

        public double getPosA() {
            return posA;
        }

        public void setPosA(double posA) {
            this.posA = posA;
        }

        public double getPosB() {
            return posB;
        }

        public void setPosB(double posB) {
            this.posB = posB;
        }

        public double getPosC() {
            return posC;
        }

        public void setPosC(double posC) {
            this.posC = posC;
        }
        @Override
        public String toString() {
            return  "<" +
                    "X: " + getPosX() + ", " +
                    "Y: " + getPosY() + ", " +
                    "Z: " + getPosZ() + ", " +
                    "A: " + getPosA() + ", " +
                    "B: " + getPosB() + ", " +
                    "C: " + getPosC() +
                    ">";
        }

        public int getPosNum() {
            return posNum;
        }

        public void setPosNum(int posNum) {
            this.posNum = posNum;
        }
    }
}


public class MainWindow {

    private Thread dataServerThread;
    private SimpleDataServer dataServer;
    private XmlParserGlobalVarsRD globalVarPLC, globalVarKRC;
    private JFrame frame;
    private JTextField simpleWorkingDirStiffness;
    private JTextField simpleWorkingDirAdditionalForce;
    private JTextField simpleTravelDistance;
    private JTextField simpleTravelVelocity;
    private JTextField simpleTotalTime;
    private JTextField simpleTheoreticalDepth;
    private JTextField simpleZProgress;
    private JComboBox oscillationMode;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Throwable e) {
            e.printStackTrace();
        }
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainWindow window = new MainWindow();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public MainWindow() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {

        final JCheckBox emptyScanCycle = new JCheckBox("VRSI Scan Cycle Plain Fasteners");

        //set data server thread and start it
        dataServer = new SimpleDataServer(30008);
        dataServerThread = new Thread(dataServer);
        dataServerThread.setDaemon(true);
        dataServerThread.start();

...

        JButton pbUpdate = new JButton("UPDATE");
        pbUpdate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                System.out.println(dataServer.getRecPositions().size()) 
            }
        });
        pbUpdate.setBounds(210, 176, 90, 28);
        frame.getContentPane().add(pbUpdate);

    }

我认为问题出在您的 SimpleDataServer.run 方法中。您正在从 SimpleDataServer 实例中创建一个单独的 SimpleDataServer 实例。因此,所有通信都发生在您的 MainWindow 没有直接引用的对象中。我相信您的 SimpleDataServer.run 方法应该如下所示:

@Override
public void run() {
    this.startServer();
}