2016-04-22 107 views
0

我在過去一週一直在使用這個應用程序。目標是有兩個聊天窗口(一個將作爲服務器),它們將在它們之間交換消息。
我得到它的工作,他們都可以連接的點。服務器可以接收消息並將其顯示在文本區域中,但是,我無法將其發送到服務器,以便將消息發送到客戶端,並讓客戶端在其文本區域中顯示它們。 這裏是我的服務器代碼:使用Java套接字的基本聊天程序,客戶端沒有收到來自服務器的消息

package fxJava; 

import java.io.*; 
import java.net.*; 

import javafx.application.Application; 

import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.ScrollPane; 
import javafx.scene.control.TextArea; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class Server extends Application implements Runnable { 
@Override // Override the start method in the Application class 

public void start(Stage primaryStage) { 


// Create a scene and place it in the stage 
Scene scene = new Scene(chatScreen(), 600, 450); 
primaryStage.setTitle("Server Chat"); // Set the stage title 
primaryStage.setScene(scene); // Place the scene in the stage 
primaryStage.show(); // Display the stage 

//Creating the thread 

Thread hilo = new Thread(this); 
hilo.start(); 
// event to send messages after pressing enter 
textMessage.setOnAction(e ->{ 
    try { 
      String MessageOut = textMessage.getText(); 
      chatScreen.appendText("Server says: " + MessageOut + '\n'); 

      outputToClient.writeUTF(MessageOut); 

      outputToClient.flush(); 

     } catch (Exception e1) { 
      e1.printStackTrace(); 

     } 
    }); 

} 
static ServerSocket serverSocket; 
static Socket socket; 
static String MessageIn = ""; 
static DataInputStream inputFromClient; 
static DataOutputStream outputToClient; 
static TextArea chatScreen = new TextArea(); 
static TextField textMessage = new TextField("Hola"); 


// PANE FOR INPUT OBJECTS 
public static HBox messageArea(){ 

HBox messageArea = new HBox(); 
messageArea.setPadding(new Insets(15, 5, 5, 5)); 

textMessage.setPrefSize(550, 50); 

messageArea.getChildren().addAll(textMessage); 

return messageArea; 

} 
//create pane for chat window 
public static VBox chatScreen(){ 

VBox chat = new VBox(); 
chatScreen.setPrefSize(600, 400); 
chatScreen.setEditable(false); 
chat.getChildren().addAll(new ScrollPane(chatScreen), messageArea()); 

return chat; 
} 


public static void main(String[] args){ 
    Application.launch(args); 


} 

public void run(){ 
    try{ 
     // Create a server socket 
       serverSocket = new ServerSocket(8052); 
      while(true){ 
       // Listen for a connection request 
       socket = serverSocket.accept(); 

     // Create data input and output streams 
       inputFromClient = new   DataInputStream(socket.getInputStream()); 
       outputToClient = new   DataOutputStream(socket.getOutputStream()); 

       /// READING DATA FROM CLIENT 
      MessageIn = inputFromClient.readUTF(); 
      chatScreen.appendText("Client says: " + MessageIn + '\n'); 

      socket.close(); 

      } 
      }catch (IOException e) { 
      e.printStackTrace(); 
      } 
    textMessage.setText(""); 

} 
} 

這是客戶端代碼

package fxJava; 

import java.io.*; 
import java.net.*; 

import javafx.application.Application; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.ScrollPane; 
import javafx.scene.control.TextArea; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class Client extends Application implements Runnable { 

@Override // Override the start method in the Application class 
public void start(Stage primaryStage) { 




// Create a scene and place it in the stage 
Scene scene = new Scene(chatScreen(), 600, 450); 
primaryStage.setTitle("Client Chat"); // Set the stage title 
primaryStage.setScene(scene); // Place the scene in the stage 
primaryStage.show(); // Display the stage 

Thread clientHilo = new Thread(this); 
clientHilo.start(); 

//event for text box 
textMessage.setOnAction(e ->{ 
    try { 
      //creating socket 
      socket = new Socket("127.0.0.1", 8052); 

      String MessageOut = textMessage.getText(); 
      chatScreen.appendText("Client says:" + MessageOut + '\n'); 
      outputToClient = new DataOutputStream(socket.getOutputStream()); 
      inputFromClient = new DataInputStream(socket.getInputStream()); 
      outputToClient.writeUTF(MessageOut); 

      while(true){ 
       MessageIn = inputFromClient.readUTF(); 
       chatScreen.appendText("Client says: " + MessageIn + '\n'); 

      } 




      //socket.close(); 
     } catch (Exception e1) { 
      // TODO Auto-generated catch block 

     } 
    textMessage.setText(""); 
    }); 

} 
static Socket socket; 
static String MessageIn = ""; 
static DataInputStream inputFromClient; 
static DataOutputStream outputToClient; 
static TextArea chatScreen = new TextArea(); 
static TextField textMessage = new TextField("Hola"); 


// PANE FOR INPUT OBJECTS 
public static HBox messageArea(){ 

HBox messageArea = new HBox(); 
messageArea.setPadding(new Insets(15, 5, 5, 5)); 

textMessage.setPrefSize(550, 50); 

messageArea.getChildren().addAll(textMessage); 

return messageArea; 

} 
//create pane for chat window 
public static VBox chatScreen(){ 

VBox chat = new VBox(); 
chatScreen.setPrefSize(600, 400); 
chatScreen.setEditable(false); 
chat.getChildren().addAll(new ScrollPane(chatScreen), messageArea()); 

return chat; 
} 


public static void main(String[] args){ 
    Application.launch(args); 


} 

public void run(){ 

    try{ 



     while(true){ 

     //I TRIED TO MOVE THE DATA STREAM HERE, BUT THEN CONNECTION IS LOST 



     } 
    }catch (Exception e2){ 

    } 
} 

} 

預先感謝您的任何建議。

回答

0

基本上,你有三種選擇:

  1. 不要在一個雙向的方式通信以同樣的方式,即「客戶端」也將打開它監聽服務器套接字,和所有的一切不再有客戶端或服務器,但兩個程序以相同的方式進行通信。

  2. 使用持久套接字從客戶端連接到服務器:爲客戶端建立連接「全局」(如在操作方法中不是本地的),並讓線程監聽傳入數據。在服務器端,持有對活動客戶端套接字的引用,並使用它向客戶端發送消息。

  3. 使用某種忙碌輪詢,即客戶端連接到服務器,每個n秒,問「你有什麼信息給我?」並且服務器做出相應的響應。

所有的優點和缺點:(1)意味着你將不得不打開客戶端的防火牆以允許連接,這是管理員的噩夢。另一方面,這是最容易實現的。 (2)意味着你必須以某種方式應對網絡丟失並解決它(不幸的是,網絡大多不像我們希望的那樣一致。)除此之外,它是資源最多的網絡,保留路要走。 (3)意味着你有一個簡單而強大的解決方案,但是你將浪費大量的CPU和網絡帶寬來進行無結果的查詢 - 回答週期。再一次,這很容易實現。

相關問題