努力将字符串从客户端传递到服务器
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;
}
}
}
您可以将 Client
和 Server
分成它们自己的 classes,我只是将它们保留为静态 classes 以便将它们放入主 class。我还从您的代码中删除了 while(true)
循环。仅当您想要继续检查套接字时才需要循环。服务器 class 中的代码也将挂在 readLine()
直到客户端发送一些东西(您可以通过在 stream.println()
之前在客户端的连接函数中放置一个 Thread.sleep()
调用来测试它.
所以你无法通过 server.startServer() 的原因是因为它在主线程中 运行 并挂起所有内容。
寻求帮助!我一直试图让这个工作太久了。我最初尝试将服务器和它的 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;
}
}
}
您可以将 Client
和 Server
分成它们自己的 classes,我只是将它们保留为静态 classes 以便将它们放入主 class。我还从您的代码中删除了 while(true)
循环。仅当您想要继续检查套接字时才需要循环。服务器 class 中的代码也将挂在 readLine()
直到客户端发送一些东西(您可以通过在 stream.println()
之前在客户端的连接函数中放置一个 Thread.sleep()
调用来测试它.
所以你无法通过 server.startServer() 的原因是因为它在主线程中 运行 并挂起所有内容。