努力将字符串从客户端传递到服务器

Struggling with passing String from Client to Server

寻求帮助!我一直试图让这个工作太久了。我最初尝试将服务器和它的 JavaFX 部分(实际阶段、启动方法等)放在同一个 Class 中,但经过数小时的尝试后,我继续将它们分开并从头开始尝试。可惜没有运气。

这是我的服务器:

public class Server
{
    String s = "";
   public void startServer() throws UnknownHostException, IOException
    {
        ServerSocket server = new ServerSocket (8896);
        while(true)
        {
                    Socket socket = null;
                    try
                    {
                            socket = server.accept();
                            System.out.println("Connected");
                            BufferedReader dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                            s = dis.readLine();
                            System.out.println(dis.readLine());
                    }
                    catch(IOException e){}
                    finally
                    {
                        if(socket != null)
                            try
                            {
                                    socket.close();
                            }
                            catch(IOException e){}
                    }
            }
    }
    public  String giveString()
    {
        return s;
    }
}

我的客户:

public class Client
{
    private String string = "";
    private Socket s;

    public void connect() throws UnknownHostException, IOException
    {
        s = new Socket("localhost",8896);
        PrintStream dos = new PrintStream(s.getOutputStream(),true);
        dos.println(string);
        dos.flush();
        s.close();   
    }

    public void setString(String string)
    {
        this.string = string;
    }
}

最后,我的 ServerGUI class。我想在我添加到场景的 TextField 中显示通过 Client->Server.giveString()->ServerGUI 传递的字符串 s

public class ServerGUI extends Application
{
    private TextField tf = new TextField("");
    private static Server server = new Server();
    private SimpleStringProperty ssp = new SimpleStringProperty();

    public void initialize() throws UnknownHostException, IOException
    {


        ssp.bind(tf.textProperty());
        tf.textProperty().set(server.giveString());
        ssp.setValue(server.giveString());
        server.startServer();
    }

    public void start(Stage primaryStage) throws UnknownHostException, IOException
    {
        VBox root = new VBox();
        Scene scene = new Scene(root, 380, 200);
        root.getChildren().add(tf);
        primaryStage.setScene(scene);
        primaryStage.show();
        server.startServer();
    }

    public static void main(String[] args) throws UnknownHostException, IOException
    {

        launch(args);
    }

}

我试着把 server.startServer();已经在 ServerGUI 中的不同位置,结果不同。从未找到解决方案。我确信这很简单,如果有人能给我一些指示,我将不胜感激。我根本没有取得任何进展,我觉得我尝试了这里的每一个想法。

您的代码存在问题,您的服务器 class 调用了 accept()。等待客户端套接字启动。您的代码永远不会通过这一点,因为线程只是在那里等待。您可以查看我在下面发布的代码,看看这是真的。我在创建客户端的线程中有一个 Thread.sleep(6000)(6 秒),因此您可以看到服务器在接受 Socket 之前永远不会打印出 "Connected"。

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class Test extends Application
{
    private Label tf = new Label("");
    private static Server server = new Server();

    @Override
    public void start(Stage primaryStage)
    {
        VBox root = new VBox();
        Scene scene = new Scene(root, 380, 200);
        root.getChildren().add(tf);
        primaryStage.setScene(scene);
        primaryStage.show();

        tf.textProperty().bind(server.passedStringValProperty());

        new Thread(() -> {
            try {
                server.startServer();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }, "Server socket listener").start();

        new Thread(() -> {
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Client client = new Client();
            client.setString("Hello world!");
            try{
                client.connect();
            } catch (IOException e) {
                e.printStackTrace();
            }


        }, "Client connection").start();
    }

    public static void main(String[] args) throws UnknownHostException, IOException
    {
        launch(args);
    }

    private static class Server
    {

        public SimpleStringProperty passedStringValProperty () {
            return passedStringVal;
        }

        private SimpleStringProperty passedStringVal = new SimpleStringProperty();

        public void startServer () throws UnknownHostException, IOException {
            ServerSocket server = new ServerSocket(8896);

            // Removed while loop since you only need 1 instance
            Socket socket = null;
            try {
                socket = server.accept();
                System.out.println("Connected");
                BufferedReader dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                final String passedVal = dis.readLine();

                Platform.runLater(() -> {
                            passedStringVal.set(passedVal);
                        });

                System.out.println(passedVal);
            } catch (IOException ignored) {
            } finally {
                if (socket != null)
                    try {
                        socket.close();
                    } catch (IOException ignored) {
                    }
            }
        }
    }

    private static class Client{
        private String string = "";
        private Socket s;

        public void connect() throws IOException
        {
            s = new Socket("localhost",8896);
            PrintStream stream = new PrintStream(s.getOutputStream(),true);
            stream.println(string);
            s.close();
        }

        public void setString(String string)
        {
            this.string = string;
        }
    }
}

您可以将 ClientServer 分成它们自己的 classes,我只是将它们保留为静态 classes 以便将它们放入主 class。我还从您的代码中删除了 while(true) 循环。仅当您想要继续检查套接字时才需要循环。服务器 class 中的代码也将挂在 readLine() 直到客户端发送一些东西(您可以通过在 stream.println() 之前在客户端的连接函数中放置一个 Thread.sleep() 调用来测试它.

所以你无法通过 server.startServer() 的原因是因为它在主线程中 运行 并挂起所有内容。