繁体   English   中英

具有Java套接字的基本聊天程序,客户端未从服务器接收消息

[英]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){

    }
}

}

预先感谢您的任何建议。

基本上,您有三个选择:

  1. 双向进行相同的通信方式,即“客户端”也打开它监听的服务器套接字,总之不再有客户端或服务器,而是两个程序以相同的方式通信。

  2. 使用持久套接字从客户端到服务器进行连接:为客户端建立“全局”连接(对于action方法而言不是本地的),并让线程侦听传入的数据。 在服务器端,保留对活动客户端套接字的引用,并使用该引用将消息发送到客户端。

  3. 使用某种繁忙的轮询,即客户端每n秒连接一次服务器,询问“您有什么要给我的消息吗?” 服务器相应地做出响应。

它们各有利弊:(1)意味着您必须打开客户端的防火墙以允许连接,这是一场管理员梦m。 另一方面,这是最容易实现的。

(2)意味着您必须以某种方式应对网络掉线并加以解决(不幸的是,网络大多不如我们希望的那样一致。)除此之外,这是最节省资源的一种方式。

(3)意味着您拥有一个简单而强大的解决方案,但是在无结果的查询-回答周期中,您将浪费大量的CPU和网络带宽。 再一次,这很容易实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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