[英]Basic Chat Program with Java sockets, Client not receiving messages from 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("");
}
}
这是客户端代码
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){
}
}
}
预先感谢您的任何建议。
基本上,您有三个选择:
双向进行相同的通信方式,即“客户端”也打开它监听的服务器套接字,总之不再有客户端或服务器,而是两个程序以相同的方式通信。
使用持久套接字从客户端到服务器进行连接:为客户端建立“全局”连接(对于action方法而言不是本地的),并让线程侦听传入的数据。 在服务器端,保留对活动客户端套接字的引用,并使用该引用将消息发送到客户端。
使用某种繁忙的轮询,即客户端每n秒连接一次服务器,询问“您有什么要给我的消息吗?” 服务器相应地做出响应。
它们各有利弊:(1)意味着您必须打开客户端的防火墙以允许连接,这是一场管理员梦m。 另一方面,这是最容易实现的。
(2)意味着您必须以某种方式应对网络掉线并加以解决(不幸的是,网络大多不如我们希望的那样一致。)除此之外,这是最节省资源的一种方式。
(3)意味着您拥有一个简单而强大的解决方案,但是在无结果的查询-回答周期中,您将浪费大量的CPU和网络带宽。 再一次,这很容易实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.