简体   繁体   中英

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:

  1. 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.

  2. 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. On the server side, hold a reference to the active client socket, and use that to send messages to the client.

  3. Use some kind of busy polling, ie the client connects to the server each n seconds, asks "do you have any message for me?" 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. 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.

(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. Once more, this is quite easy to implement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM