寻求帮助!我一直在努力使其工作太久了。我最初尝试将服务器和JavaFX的一部分(实际的阶段,启动方法等)放在同一个类中,但是经过数小时的尝试,我又将它们分开进行尝试。可惜没有运气。
在这里我的服务器:
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类。我想在我添加到场景的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中已经处于不同位置,结果也不同。从未找到解决方案。我肯定这很简单,如果有人可以给我一些指示,我将非常感激。我只是根本没有取得任何进展,感觉就像我在这里尝试过的每个想法一样。
答案 0 :(得分:1)
您的代码存在问题,因为您的服务器类已调用accept()
。等待客户端套接字启动。由于线程仅在此处等待,因此您的代码永远都不会通过。您可以查看我在下面发布的代码,以了解是否正确。我在创建客户端的线程中有一个Thread.sleep(6000)
(6秒),因此您可以看到服务器在接受Socket
之前永远不会打印出“已连接”。
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
分成各自的类,我只是将它们保留为静态类以使其适合主类。我还从您的代码中删除了while(true)
循环。仅当您要继续检查套接字时才需要循环。服务器类中的代码也将挂在readLine()
上,直到客户端发送一些内容为止(您可以通过在客户端Thread.sleep()
之前的客户端连接函数中放置一个stream.println()
调用来进行测试。
所以您无法通过server.startServer()的原因是因为它正在主线程中运行并挂起了所有内容。