在 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();
}
使用 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();
}