过去一周我一直在这个应用程序中工作。目标是有两个聊天窗口(一个将作为服务器),它们将在它们之间交换消息 我让它工作到他们都可以连接的程度。服务器可以接收消息并在文本区域显示它们,但是,我无法做到这一点,因此服务器将消息发送到客户端并让客户端在其文本区域中显示它们。 这是我的服务器代码:
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 :(得分:0)
基本上,您有三种选择:
以双向方式进行相同的通信方式,即“客户端”也会打开它侦听的服务器套接字,总而言之,不再有客户端或服务器,而是两个程序进行通信以同样的方式。
使用持久套接字从客户端连接到服务器:为客户端建立连接“全局”(如操作方法的非本地连接),并让线程侦听传入数据。在服务器端,保留对活动客户端套接字的引用,并使用该引用向客户端发送消息。
使用某种忙碌轮询,即客户端每 n 秒连接到服务器,询问“你有什么消息给我吗?”并且服务器做出相应的响应。
所有都有它们的优点和缺点:(1)意味着你必须打开客户端的防火墙以允许连接,这是一个管理员的噩梦。另一方面,它是最容易实现的。
(2)意味着你必须以某种方式应对网络丢弃并解决它(不幸的是,网络大多不像我们希望的那样一致。)除此之外,它是最节省资源的要走的路。
(3)意味着您有一个简单而强大的解决方案,但是您将浪费大量的CPU和网络带宽用于无结果查询 - 应答周期。再一次,这很容易实现。