5

私はJavaとJavaFXを初めて使用するので、初心者の質問はご容赦ください。私は過去数日間、私がやろうとしていることの例を探しましたが、答えを見つけることができませんでした。私がやろうとしていることは次のとおりです。サーバーに接続してデータを送受信するシーンビルダーを使用して、単純なjavafxGUIクライアントソケットアプリケーションを作成しようとしています。簡単ですが、これをJava FXで実装しようとすると、GUIがフリーズします。調査したところ、ソケット通信に時間がかかり、javafxGUIが更新できないことが原因であることがわかりました。私の調査では、タスクを使用することが示されています。そこで、タスクを作成し、インターネットソケット(ポート80)に接続し、コマンド「GET / HTTP / 1.1 \ r \ n \ r \ n」を送信してページを要求し、印刷する簡単なアプリケーションを作成しました。受信した各行。問題は、これを何度も(3秒ごとに)実行したいということです。タスクは一度は正常に実行されますが、その後停止します。次のコードでは、スレッドをスリープ状態にする行には到達しませんが、エラーを出力する行もsystem.outに送信されません。

これがコントローラーコードです

package clientSocketExample;

import java.io.*;
import java.net.*;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.concurrent.Task;

/**
 * Controller class of the HelloWorld sample.
 */
public class ClientSocketExampleController implements Initializable
{

    @FXML
    Button button;

    private boolean keepRunning = true;

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rsrcs)
    {
            if (button != null)
        {
            button.setOnAction(new EventHandler<ActionEvent>()
            {
                @Override
                public void handle(ActionEvent event)
                {
                    keepRunning = false;
                    System.out.println("Hello World\n");
                }
            });
        }

        // Create a background task to handle the Client-Server socket
        // This is needed because JavaFX is not thread safe
        Task<Integer> task = new Task<Integer>()
        {
             @Override
            protected Integer call() throws Exception
            {
                Socket s = new Socket();
//                String host = "www.google.com";
//                String host = "www.amazon.com";
                String host = "www.yahoo.com";
                PrintWriter s_out = null;
                BufferedReader s_in = null;
                int lineNums = 0;

                try
                {
                    s.connect(new InetSocketAddress(host, 80));
                    System.out.println("Connected\n");

                    // Create writer for socket
                    s_out = new PrintWriter(s.getOutputStream(), true);

                    // Create reader for socket
                    s_in = new BufferedReader(new     InputStreamReader(s.getInputStream()));
                }
                catch (IOException e)
                {
                    // Host not found, so print error
                    System.err.println("Don't know about host : " + host);
                    System.exit(1);
                }

                // Loop forever waiting for task to be cancelled
                while (isCancelled() == false)
                {
                    // Send message to server
                    String message = "GET / HTTP/1.1\r\n\r\n";
                    s_out.println(message);

                    System.out.println("Message sent\n");
                    // Get response from server
                    try
                    {
                        String response;
                        while ((response = s_in.readLine()) != null)
                        {
                            System.out.print("Line #: "+lineNums+" ");
                            System.out.println(response);
                            lineNums++;
                        }
                    } catch (IOException e)
                    {
                        System.err.println("Couldn't get response from host");
                    }

                    System.out.println("Thread going to sleep\n\n\n");
                    Thread.sleep(3000);
                    System.out.println("Thread waking up from sleep\n\n\n");
                } // End while

                return lineNums;
            }           
        }; // End Initialize

        // start the background task
        Thread th = new Thread(task);
        th.setDaemon(true);
        System.out.println("Starting background task...");
        th.start();
    }
}`

Main.javaクラスは次のようになります。

package clientSocketExample;

import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class Main extends Application
{
/**
 * @param args the command line arguments
 */
public static void main(String[] args)
{
    Application.launch(Main.class, (java.lang.String[]) null);
}

@Override
public void start(Stage primaryStage)
{
    try
    {
        AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class
                .getResource("ClientSocketExample.fxml"));
        Scene scene = new Scene(page);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Hello World Sample");
        primaryStage.show();
    } catch (Exception ex)
    {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
    }
}

} `

そして最後に、FXMLファイルは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<AnchorPane id="AnchorPane" prefHeight="365.0" prefWidth="378.0"     xmlns:fx="http://javafx.com/fxml"     fx:controller="clientSocketExample.ClientSocketExampleController">
  <children>
    <Button fx:id="button" layoutX="147.0" layoutY="28.0" text="Connect" />
    <TitledPane animated="false" layoutY="159.0" prefWidth="378.0" text="Received Data">
      <content>
        <AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
          <children>
            <TextArea fx:id="textAreaField" prefHeight="180.0" prefWidth="374.0" wrapText="true" />
          </children>
        </AnchorPane>
      </content>
    </TitledPane>
  </children>
</AnchorPane>

ウェインを助けてくれてありがとう

4

2 に答える 2

0

フリーズするGuiで発生している問題は、ソケットに接続する「コントローラー」クラスが原因です。JavaFx および JavaFx シーン ビルダーを使用して独自のチャット プログラムを作成していたときに、同じ問題が発生しました。

次の 2 つのことを行うことができます。

  1. SocketConnector()ソケットに接続する新しいクラス ( ) を作成します。

  2. 代わりにメインクラス内のソケットに接続しますcontroller

コントローラ クラス内のソケットに接続できないにもかかわらず、申し訳ありませんが、この問題を数回経験したことを知っているだけで、それを修正する方法を知ることができない理由の詳細を説明できません。

于 2013-02-25T09:50:43.957 に答える
0

リクエストに合わせていくつか変更する必要があります。

  1. これをリクエストに挿入します

    "\r\nHost: <host>\r\nConnection: keep-alive"
    

    これにより、リクエストに応答した後、サーバーが接続を閉じないようにすることができます。

  2. while ループを次のように変更します。

    while (s_in.ready() && (response = s_in.readLine()) != null)
    

    これにより、BufferedReader から読み取るものがあることが確認されます。BufferedReader がハングする理由については、次の投稿を確認してください

于 2014-03-26T22:03:33.270 に答える