[英]Basic Chat Program with Java sockets, Client not receiving messages from Server
I have been working in this application in the past week. 过去一周,我一直在使用此应用程序。 The goal is to have two chat windows (one will work as the server) that will exchange messages between them.
目标是要有两个聊天窗口(一个将作为服务器)在它们之间交换消息。
I got it to work to the point that they both can connect. 我认为它们都可以连接。 The server can receive messages and show them in a text area, however, i cannot make it so the server sends the messages to the client and have the client show them in its Text area.
服务器可以接收消息并在文本区域中显示它们,但是,我无法做到这一点,因此服务器将消息发送给客户端,并让客户端在其文本区域中显示它们。 Here is my server 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 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("");
}
}
And this is the 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){
}
}
}
Thank you in advance for any suggestion. 预先感谢您的任何建议。
Basically, you have three options: 基本上,您有三个选择:
Do the same way of communication in a bi-directional way, ie the "client" also opens a server socket that it listens to, and all in all there is no client or server anymore, but two programs communicating in the same way. 双向进行相同的通信方式,即“客户端”也打开它监听的服务器套接字,总之不再有客户端或服务器,而是两个程序以相同的方式通信。
Use a persistent socket to connect from client to server: make the connection "global" (as in not-local to the action method) for your client, and have a thread listen to incoming data. 使用持久套接字从客户端到服务器进行连接:为客户端建立“全局”连接(对于action方法而言不是本地的),并让线程侦听传入的数据。 On the server side, hold a reference to the active client socket, and use that to send messages to the client.
在服务器端,保留对活动客户端套接字的引用,并使用该引用将消息发送到客户端。
Use some kind of busy polling, ie the client connects to the server each n seconds, asks "do you have any message for me?" 使用某种繁忙的轮询,即客户端每n秒连接一次服务器,询问“您有什么要给我的消息吗?” and the server responds accordingly.
服务器相应地做出响应。
All have their pros and cons: (1) means that you will have to open up the firewall of the client to allow connections, which is an admin-nightmare. 它们各有利弊:(1)意味着您必须打开客户端的防火墙以允许连接,这是一场管理员梦m。 On the other hand, it is the easiest to implement.
另一方面,这是最容易实现的。
(2) Means that you have to somehow cope with network drop and work around it (as unfortunately networks are mostly not as consistent as we'd like them to be.) Apart from that, it is the most resource-preserving way to go. (2)意味着您必须以某种方式应对网络掉线并加以解决(不幸的是,网络大多不如我们希望的那样一致。)除此之外,这是最节省资源的一种方式。
(3) Means that you have a simple and robust solution, but you will waste a lot of CPU and network bandwidth for no-result query-answer cycles. (3)意味着您拥有一个简单而强大的解决方案,但是在无结果的查询-回答周期中,您将浪费大量的CPU和网络带宽。 Once more, this is quite easy to implement.
再一次,这很容易实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.