服务器:
package net;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Exercise31_01Server extends Application {
private ExecutorService executor = Executors.newFixedThreadPool(5); //线程池(管理线程数量)
private TextArea textArea = new TextArea(); //文本区域(显示信息)
private static final int SERVER_PORT = 8000; //端口号
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
//文本区域(设置属性)
textArea.setPrefColumnCount(40);
textArea.setPrefRowCount(10);
textArea.setEditable(false);
Scene scene = new Scene(new ScrollPane(textArea));
primaryStage.setScene(scene);
primaryStage.setTitle("Exercise31_01Server");
primaryStage.show();
//启动线程
new Thread(this::startServer).start();
}
/** 启动服务器 */
private void startServer() {
try {
//创建服务器套接字
ServerSocket server = new ServerSocket(SERVER_PORT);
Platform.runLater(() -> textArea.appendText(this.getClass().getSimpleName() + " started at " + new Date() + "\n"));
while (true) {
//创建套接字(连接客户端)
Socket socket = server.accept();
Platform.runLater(() -> textArea.appendText("Connected to a client at " + new Date() + "\n"));
//为连接的客户端分配一个线程
executor.execute(new HandleClient(socket));
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
executor.shutdown();
}
}
/** 内部类-处理一个客户端 */
private class HandleClient implements Runnable {
private Socket socket; //连接客户端的套接字
public HandleClient(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
//输入、输出流
DataInputStream inputFromClient = null;
DataOutputStream outputToClient = null;
try {
inputFromClient = new DataInputStream(socket.getInputStream());
outputToClient = new DataOutputStream(socket.getOutputStream());
while (true) {
//获取客户端数据
double annualInterestRate = inputFromClient.readDouble();
int numberOfYears = inputFromClient.readInt();
double loanAmount = inputFromClient.readDouble();
double monthlyRate = annualInterestRate / 1200;
double monthlyPayment = loanAmount * monthlyRate / (1 - 1 / Math.pow(1 + monthlyRate, numberOfYears * 12));
double totalPayment = monthlyPayment * 12 * numberOfYears;
//写数据到客户端
outputToClient.writeDouble(monthlyPayment);
outputToClient.writeDouble(totalPayment);
Platform.runLater(() ->
textArea.appendText("Annual Interest Rate: " + annualInterestRate + "\n" +
"Number of Year: " + numberOfYears + "\n" +
"Loan Amount: " + loanAmount + "\n" +
"monthlyPayment: " + monthlyPayment + "\n" +
"totalPayment: " + totalPayment + "\n\n"));
}
} catch (IOException ex) {
textArea.appendText(ex.getMessage());
} finally {
try { //关闭流
if (inputFromClient != null) inputFromClient.close();
if (outputToClient != null) outputToClient.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}
客户端:
package net;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class Exercise31_01Client extends Application {
private TextField annualInterestRate = new TextField(); //年利息率
private TextField numberOfYears = new TextField(); //年数
private TextField loanAmount = new TextField(); //贷款数量
private Button submit = new Button("Submit"); //提交
private TextArea message = new TextArea(); //文本区域(显示信息)
private static final String HOST = "localhost"; //主机/IP地址
private static final int SERVER_PORT = 8000; //端口号
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
//总面板
BorderPane pane = new BorderPane(new ScrollPane(message));
pane.setTop(getTopPane());
//文本区域设置属性
message.setPrefRowCount(6);
message.setPrefColumnCount(30);
message.setEditable(false);
//按钮设置动作事件
submit.setOnAction(event -> handleSubmit());
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.setTitle("Exercise31_01Client");
primaryStage.show();
}
/** 返回顶部面板 */
private GridPane getTopPane() {
//网格面板(放置文本域)
GridPane pane = new GridPane();
pane.setStyle("-fx-hgap: 10px; -fx-vgap: 5px;");
pane.addRow(0, new Label("Annual Interest Rate:"), annualInterestRate);
pane.addRow(1, new Label("Number of Years:"), numberOfYears);
pane.addRow(2, new Label("Loan Amount:"), loanAmount);
pane.add(submit, 2, 1);
//文本域设置属性
annualInterestRate.setAlignment(Pos.BOTTOM_RIGHT);
numberOfYears.setAlignment(Pos.BOTTOM_RIGHT);
loanAmount.setAlignment(Pos.BOTTOM_RIGHT);
annualInterestRate.setPrefColumnCount(13);
numberOfYears.setPrefColumnCount(13);
loanAmount.setPrefColumnCount(13);
return pane;
}
/** 提交信息给服务器 */
private void handleSubmit() {
Socket socket = null; //客户端套接字
DataInputStream inputFromServer = null; //输入流
DataOutputStream outputToServer = null; //输出流
try {
socket = new Socket(HOST, SERVER_PORT);
inputFromServer = new DataInputStream(socket.getInputStream());
outputToServer = new DataOutputStream(socket.getOutputStream());
double annualInterestRate = Double.parseDouble(this.annualInterestRate.getText().trim());
int numberOfYears = Integer.parseInt(this.numberOfYears.getText().trim());
double loanAmount = Double.parseDouble(this.loanAmount.getText().trim());
//发送数据到服务器
outputToServer.writeDouble(annualInterestRate);
outputToServer.writeInt(numberOfYears);
outputToServer.writeDouble(loanAmount);
//接受服务器数据
double monthlyPayment = inputFromServer.readDouble();
double totalPayment = inputFromServer.readDouble();
Platform.runLater(() ->
message.appendText("Annual Interest Rate: " + annualInterestRate + "\n" +
"Number of Year: " + numberOfYears + "\n" +
"Loan Amount: " + loanAmount + "\n" +
"monthlyPayment: " + monthlyPayment + "\n" +
"totalPayment: " + totalPayment + "\n\n"));
this.annualInterestRate.setText("");
this.numberOfYears.setText("");
this.loanAmount.setText("");
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try { //关闭与服务器的连接
if (socket != null) socket.close();
if (inputFromServer != null) inputFromServer.close();
if (outputToServer != null) outputToServer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}