从服务器套接字获取实时数据并在javafx中显示

问题描述 投票:-2回答:1

您好,我需要从我创建的服务器套接字中获取一些数据,并将其显示在javafx应用程序中FX应用程序,即显示屏每250毫秒刷新一次数据,服务器每2秒钟发送一次数据]

我的代码/计划主要包括3部分1.服务器生成数据,每2秒将其发送到端口2. Clint代码从服务器获取数据并更新其全局变量3.每250ms Schedule Scheduler执行器以clint形式访问全局变量并更新文本字段//可悲的是这似乎不起作用我总是启动服务器,然后clint然后运行应用程序

所以我写的代码如下

服务器代码

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DecimalFormat;
import java.util.concurrent.TimeUnit;
public class Server {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket socket;
        try (ServerSocket serverSocket = new ServerSocket(5555)) {
            System.out.println("A");
            socket = serverSocket.accept();
            System.out.println("B");
            if(socket.isConnected())System.out.println("Connected");
            DataOutputStream dout=new DataOutputStream(socket.getOutputStream());
            while (socket.isConnected()) {
                String T=DataStructureMaker();
                dout.writeUTF(T);
                System.out.println(T);
                TimeUnit.SECONDS.sleep(2);
                dout.flush();
            }
        }
        socket.close();
    } 
    public static String DataStructureMaker()
    {
    float RV_Phase=0,RI_Phase=0,RI_Grid=0,RV_Grid=0;String s="";
        DecimalFormat df = new DecimalFormat("#.00");
        s="";
        RV_Phase=Float.parseFloat(df.format((Math.random()*10)));
        s=s+Float.toString(RV_Phase)+"#";
        RI_Phase=Float.parseFloat(df.format((Math.random()*10)));
        s=s+Float.toString(RI_Phase)+"#";
        RI_Grid=Float.parseFloat(df.format((Math.random()*10)));
        s=s+Float.toString(RI_Grid)+"#";
        RV_Grid=Float.parseFloat(df.format((Math.random()*10)));
        s=s+Float.toString(RV_Grid)+"#";
        return s;
    }
}

clint代码是

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
public class Clint {
    public static String RV_Grid;
    public static String RI_Grid;
    public static String RI_Phase;
    public static String RV_Phase;
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket s=new Socket("localhost",5555);
        String S;
        DataInputStream dIn=new DataInputStream(s.getInputStream());
        while (s.isConnected()) {            
            S=dIn.readUTF();
            setData(S);
        }
    }
    public static void setData(String S)  // Decryt data and set global values
    {
        char[] A=S.toCharArray();
        int HC=0;
        String R="";
        if(A.length>2)
        for(char x:A)
        {
            if(x=='#')
            {
                switch(HC)
                {
                    case 0:
                        HC++;
                        RV_Phase=R;
                        R="";
                        break;
                    case 1:
                        HC++;
                        RI_Phase=R;
                        R="";
                        break;
                    case 2:
                        HC++;
                        RI_Grid=R;
                        R="";
                        break;
                    case 3:
                        HC++;
                        RV_Grid=R;
                        R="";
                        break;
                }
            }else{
                R=R+x;
            }
        }
    }    
}

最后是我的fxml控制器

import java.util.ResourceBundle;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
public class FXMLDocumentController implements Initializable {

    @FXML
    private TextField Text1;
    @FXML
    private TextField Text2;
    @FXML
    private TextField Text3;
    @FXML
    private TextField Text4;


    static ScheduledExecutorService scheduledExecutorService;
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO

        scheduledExecutorService =         Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            setData();

            }, 0, 250, TimeUnit.MILLISECONDS);
    }    
    public void setData()
    {
        Text1.setText(Clint.RI_Grid);
        Text2.setText(Clint.RI_Phase);
        Text3.setText(Clint.RV_Grid);
        Text4.setText(Clint.RV_Phase);
    }       
}

上面的代码具有我的程序加密,解密发送接收和显示所需的所有无效数据

java sockets javafx serversocket
1个回答
0
投票
以下代码旨在用于两个目的:一个是针对所提出的问题演示mre。另一种是使用客户端接收的数据动态更新GUI的解决方案。该代码并非旨在显示如何正确实现客户端和服务器。

有关MRE的几点注意事项:1.它不应代表您的特定应用,而应代表您所关注的特定问题正在尝试解决。2.应该是M:删除所有不必要的内容。最低裸机。3.应该是R:重现问题。4.应该完整。独立于数据库,文件或其他不可用资源。5.应该易于使用(复制过去)。

为了使用客户端接收到的数据动态更新GUI,我使用了共享模型,该模型由客户端更新。通过使用绑定,模型中的任何更改都会反映在GUI中。

为了简单易用,我将控制器,模型,服务器和客户端都放在一个文件中FXMLDocumentController.java

import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.URL; import java.text.DecimalFormat; import java.util.ResourceBundle; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javafx.beans.property.ReadOnlyStringWrapper; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.TextField; public class FXMLDocumentController implements Initializable { private static int PORT_NUMBER = 5555; @FXML private TextField text1; @FXML Button stopButton, startButton; private ScheduledExecutorService scheduledExecutorService; private Model model; private Client client; private Server server; @Override public void initialize(URL url, ResourceBundle rb) { startButton.setDisable(false); stopButton.setDisable(true); scheduledExecutorService = Executors.newScheduledThreadPool(2); model = new Model(); text1.textProperty().bind(model.getTextProperty()); } private void startServer(){ try { server = new Server(PORT_NUMBER); server.start(); } catch (IOException ex) { ex.printStackTrace(); } } private void startClient(){ try { client = new Client(PORT_NUMBER, model); client.start(); } catch (IOException ex) { ex.printStackTrace(); } } public void start(){ scheduledExecutorService.submit(() -> startServer()); scheduledExecutorService.submit(() -> startClient()); startButton.setDisable(true); stopButton.setDisable(false); } public void stop(){ client.stop(); server.stop(); scheduledExecutorService.shutdown(); stopButton.setDisable(true); } } class Model { private final ReadOnlyStringWrapper textProperty; Model() { textProperty = new ReadOnlyStringWrapper(); } synchronized void setText(String s){ textProperty.set(s); } ReadOnlyStringWrapper getTextProperty(){ return textProperty; } } class Server { private final int portNumber; private boolean stop = false; private static long REFRESH_TIME = 2; public Server(int portNumber) { this.portNumber = portNumber; } void start() throws IOException { Socket socket; try (ServerSocket serverSocket = new ServerSocket(portNumber)) { socket = serverSocket.accept(); DataOutputStream dout=new DataOutputStream(socket.getOutputStream()); while (socket.isConnected() && ! stop) { dout.writeUTF(RandomText()); try { TimeUnit.SECONDS.sleep(REFRESH_TIME); } catch (InterruptedException ex) { break; } dout.flush(); } } } private String RandomText() { DecimalFormat df = new DecimalFormat("#.00"); StringBuilder sb = new StringBuilder(df.format(Math.random()*10)); sb.append("#") .append(df.format(Math.random()*10)) ; return sb.toString(); } void stop(){ stop = true; } } class Client { private final int portNumber; private final Model model; private boolean stop = false; Client(int portNumber, Model model) { this.portNumber = portNumber; this.model = model; } void start() throws IOException { Socket socket = new Socket("localhost",portNumber); DataInputStream dIn=new DataInputStream(socket.getInputStream()); while (socket.isConnected() && ! stop) { model.setText(dIn.readUTF()); } socket.close(); } void stop(){ stop = true; } }

该控制器由FXMLDocument.fxml使用:

<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Button?> <?import javafx.scene.control.TextField?> <?import javafx.scene.layout.GridPane?> <?import javafx.scene.layout.VBox?> <VBox alignment="CENTER" prefHeight="113.0" prefWidth="232.0" spacing="10" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fx_tests.FXMLDocumentController"> <TextField fx:id="text1" alignment="CENTER" promptText="Press START " /> <GridPane> <Button fx:id="startButton" maxWidth="Infinity" onAction="#start" text="START" GridPane.columnIndex="0" /> <Button fx:id="stopButton" maxWidth="Infinity" onAction="#stop" text="STOP" GridPane.columnIndex="2" /> </GridPane> </VBox>

使用:进行测试

import java.io.IOException; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.stage.Stage; public class FxmlTest extends Application { @Override public void start(Stage primaryStage) throws IOException { Pane root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")); Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(null); } }

© www.soinside.com 2019 - 2024. All rights reserved.