2016-04-22 7 views
0

Ich habe in dieser Anwendung in der vergangenen Woche gearbeitet. Das Ziel ist, zwei Chat-Fenster zu haben (eines wird als Server funktionieren), die Nachrichten zwischen ihnen austauschen werden.
Ich habe es bis zu dem Punkt arbeiten, dass sie beide verbinden können. Der Server kann Nachrichten empfangen und sie in einem Textbereich anzeigen, aber ich kann es nicht so machen, dass der Server die Nachrichten an den Client sendet und der Client sie in seinem Textbereich anzeigt. Hier ist mein Server-Code:Basic Chat Programm mit Java Sockets, Client empfängt keine Nachrichten vom Server

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(""); 

} 
} 

Und dies ist der Client-Code

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){ 

    } 
} 

} 

Sie für jeden Vorschlag Vielen Dank im Voraus.

Antwort

0

Grundsätzlich haben Sie drei Möglichkeiten:

  1. Sie die gleiche Art und Weise der Kommunikation in einer bidirektionalen Art und Weise, dh der „Client“ eröffnet auch eine Server-Socket, der es hört, und alles in allem Es gibt keinen Client oder Server mehr, aber zwei Programme kommunizieren auf die gleiche Weise.

  2. Verwenden Sie einen permanenten Socket, um eine Verbindung vom Client zum Server herzustellen: Stellen Sie die Verbindung für Ihren Client "global" (wie in nicht-lokaler zur Aktionsmethode) her und lassen Sie einen Thread eingehende Daten abhören. Halten Sie auf der Serverseite einen Verweis auf den aktiven Client-Socket und verwenden Sie diesen, um Nachrichten an den Client zu senden.

  3. Verwenden Sie eine Art von beschäftigt Polling, d. H. Der Client verbindet sich mit dem Server jeweils n Sekunden, fragt "Hast du irgendeine Nachricht für mich?" und der Server antwortet entsprechend.

Alle haben ihre Vor- und Nachteile: (1) bedeutet, dass Sie die Firewall des Client-Verbindungen zu ermöglichen, müssen sich öffnen, was ein Admin-Alptraum. Auf der anderen Seite ist es am einfachsten zu implementieren.

(2) Bedeutet, dass Sie irgendwie mit Netzwerk-Drop bewältigen müssen und umgehen (da Netzwerke leider meist nicht so konsistent sind, wie wir es gerne hätten.) Abgesehen davon ist es das am meisten Ressourcen- Erhaltungsweg.

(3) Bedeutet, dass Sie eine einfache und robuste Lösung haben, aber Sie werden eine Menge CPU- und Netzwerkbandbreite für keine Abfrage-Antwort-Zyklen verschwenden. Dies ist wiederum einfach zu implementieren.