我正在编写一个JavaFX应用程序(它应该是一个简单的聊天应用程序)。现在,每次按下按钮,我都会尝试写OutputStream
。事实是,它不起作用,看起来信息是写的,但我无法从InputStream
读取它。
我有两个类:其中一个是接口(extends Application
)。它有一个TextField
和一个“发送”按钮。当我在文本字段中写入内容并按下此按钮时,TextField
中的文本将写入OutputStream
。另一方面,另一个类Thread
正在从InputStream
读取。即使信息被写入流,readLine()
方法也不起作用,它会一直等待接收数据。
有什么我想念的吗?提前谢谢。
JavaFX应用程序
import java.io.*;
import java.net.Socket;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class ChatApp extends Application {
int indexMsg = 0;
Socket socket;
BufferedReader br;
PrintWriter pw;
public ChatApp() throws IOException {
this.socket = new Socket("localhost", 56700);
this.pw = new PrintWriter(socket.getOutputStream());
this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
@Override
public void start(Stage primaryStage) throws IOException {
GridPane root = new GridPane();
root.setAlignment(Pos.CENTER);
root.setVgap(10);
root.setPadding(new Insets(10,10,10,10));
ScrollPane msgPane = new ScrollPane();
msgPane.setPrefSize(280, 280);
msgPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
GridPane msgPaneContent = new GridPane();
msgPaneContent.setPrefWidth(270);
msgPaneContent.setVgap(10);
FlowPane writePane = new FlowPane(10,10);
writePane.setAlignment(Pos.CENTER);
writePane.setPrefWidth(280);
TextField writeMsg = new TextField();
writeMsg.setPrefWidth(200);
writeMsg.setPromptText("Write your message");
Button send = new Button("Send");
send.setOnAction((ev) -> {
TextArea msg = new TextArea(writeMsg.getText());
msg.setMaxWidth(135);
msg.setPrefRowCount(msg.getLength()/21 + 1);
msg.setWrapText(true);
GridPane.setConstraints(msg, 0, indexMsg++);
writeMsg.deleteText(0, writeMsg.getText().length());
msgPaneContent.getChildren().add(msg);
String message = msg.getText();
pw.write(message);
System.out.println("Sent " + msg.getText());
});
writePane.getChildren().addAll(writeMsg, send);
GridPane.setConstraints(msgPane, 0, 0);
GridPane.setConstraints(writePane, 0, 1);
msgPane.setContent(msgPaneContent);
root.getChildren().addAll(msgPane, writePane);
Scene scene = new Scene(root, 300, 300);
primaryStage.setTitle("Chat App");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException {
launch(args);
}
}
接收者线程
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ChatServer extends Thread {
ServerSocket server;
Socket socket;
BufferedReader br;
PrintWriter pw;
public ChatServer() throws IOException {
server = new ServerSocket(56700);
socket = server.accept();
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pw = new PrintWriter(socket.getOutputStream());
}
public void run() {
String msg = null;
while (true) {
try {
msg = br.readLine();
} catch (IOException ex) {
System.out.println("Error");
}
System.out.println(msg);
}
}
public static void main(String[] args) throws IOException, InterruptedException {
(new ChatServer()).start();
}
}
答案 0 :(得分:1)
您的邮件不包含行尾字符。服务器中的readLine()
方法读取流中的所有内容,查找行结束标记,然后连接所有字符以形成文本行。所以你需要从客户端发送一个行尾字符。
您还应该在发送消息后刷新打印编写器 - 否则打印写入可能会在实际发送之前缓冲许多消息:
send.setOnAction((ev) -> {
TextArea msg = new TextArea(writeMsg.getText());
msg.setMaxWidth(135);
msg.setPrefRowCount(msg.getLength()/21 + 1);
msg.setWrapText(true);
GridPane.setConstraints(msg, 0, indexMsg++);
writeMsg.deleteText(0, writeMsg.getText().length());
msgPaneContent.getChildren().add(msg);
String message = msg.getText();
pw.write(message + "\n");
pw.flush();
System.out.println("Sent " + msg.getText());
});