2013-02-08 32 views
5

मैं जावा और जावाएफएक्स में नया हूं, इसलिए मेरे नौसिखिया प्रश्नों को क्षमा करें। मैंने पिछले कुछ दिनों के लिए खोज की है जो मैं करने की कोशिश कर रहा हूं, लेकिन किसी भी उत्तर को खोजने में असमर्थ रहा हूं। यह है कि मैं क्या करने की कोशिश कर रहा हूं: मैं दृश्य निर्माता का उपयोग करके एक सरल जावाफक्स जीयूआई क्लाइंट सॉकेट एप्लिकेशन बनाने की कोशिश कर रहा हूं जो सर्वर से कनेक्ट होगा और डेटा भेज/प्राप्त करेगा। काफी सरल है, लेकिन जब मैं जावा एफएक्स में इसे लागू करने का प्रयास करता हूं, तो मेरा जीयूआई फ्रीज करता है। मैंने शोध किया है और पाया है कि कारण यह है कि सॉकेट संचार हर समय ले रहा है, और जावाफक्स जीयूआई अपडेट नहीं हो सकता है। मेरे शोध ने मुझे कार्यों का उपयोग करने के लिए इंगित किया है। इसलिए, मैंने एक सरल एप्लिकेशन बनाया है जो एक कार्य बनाता है, जो इंटरनेट सॉकेट (पोर्ट 80) से जुड़ता है, "GET/HTTP/1.1 \ r \ n \ r \ n" आदेश भेजता है जो पृष्ठ का अनुरोध करेगा और फिर प्रिंट करेगा प्रत्येक पंक्ति प्राप्त हुई। समस्या यह है कि मैं इसे बार-बार करना चाहता हूं (हर 3 सेकंड)। कार्य एक बार सफलतापूर्वक चलता है, लेकिन फिर यह बंद हो जाता है। निम्नलिखित कोड में, रेखाएं जो थ्रेड को नींद में डालती हैं, कभी नहीं पहुंचती हैं, लेकिन किसी भी त्रुटि को मुद्रित करने वाली रेखाएं सिस्टम पर नहीं भेजी जाती हैं।javafx, सॉकेट प्रोग्रामिंग, और धागे

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 फ़ाइल इस तरह दिखता है:

यहाँ नियंत्रक कोड

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 वर्ग इस तरह दिखता है

<?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> 

आपकी मदद के लिए अग्रिम धन्यवाद वेन

+0

आपका आउटपुट कैसा दिखता है? दूसरे शब्दों में, सर्वर पहली बार किस तरह प्रतिक्रिया करता है? –

उत्तर

0

गुई के साथ जो समस्या हो रही है वह फ्रीज है क्योंकि यह आपकी "नियंत्रक" कक्षा है जो सॉकेट से जुड़ती है। जब मैं JavaFx और JavaFx दृश्य निर्माता का उपयोग कर अपना स्वयं का चैट प्रोग्राम बना रहा था तो मुझे भी यही समस्या थी।

आप दो कर सकते हैं:

  1. एक नया वर्ग (SocketConnector()) सॉकेट से कनेक्ट करता है कि बनाएँ।

  2. अपने मुख्य वर्ग के भीतर कनेक्ट सॉकेट के बजाय controller

की परवाह किए बिना आप अपने नियंत्रक वर्ग के भीतर एक सॉकेट से कनेक्ट नहीं कर मुझे खेद है कि मैं के बारे में विवरण का वर्णन करने में असमर्थ हूँ कर रहा हूँ तुम क्यों मैं नहीं कर सकता बस पता है कि इस समस्या ने कई बार इस समस्या का प्रयोग किया और इसे ठीक करने का तरीका क्या है!

0

कुछ बातें आपके अनुरोध के साथ बदलने की जरूरत:

  1. सम्मिलित इस आपके अनुरोध

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

    यह सुनिश्चित करें कि सर्वर अपने कनेक्शन बंद नहीं है कि यह का जवाब के बाद कर देगा में आपके अनुरोध।

  2. बदलें इस के लिए अपने जबकि पाश:

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

    यह यकीन है कि वहाँ BufferedReader से पढ़ने के लिए कुछ न कुछ है कर देगा।इन पोस्टों को जांचें कि BufferedReader क्यों लटकाएगा: https://stackoverflow.com/a/7855911/1359765 और https://stackoverflow.com/a/15510821/1359765