最近一直在学习UDP编程,写了一个基于UDP编程的简易考试小程序,该程序的服务端先从文件中获取题目与答案,再通过UDP传输到客户端,答题完后会统计答题的总题数与答对的题数。
题目文件内容:
一部分运行截图:
点击开始答题进行答题
客户端变回按照文件内题目的顺序显示题目供作答,回答完毕点击下一题,继续答题,若答案为空会提示
当回答完最后一题时
也可提前结束回答,点击结束答题
查看成绩
代码
服务端:
package work4_3;
import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
public class Server {
public static void main(String[] args) {
DatagramSocket socket_send = null;
DatagramSocket socket_receive = null;
try {
socket_send = new DatagramSocket();
socket_receive = new DatagramSocket(9001);
FileInputStream fis = new FileInputStream("titleFile/timu.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
List<String> list = new ArrayList<String>();
String line = "";
while ((line = br.readLine()) != null) {
if (line.lastIndexOf("---") < 0) {
list.add(line);
}
}
br.close();
fis.close();
isr.close();
byte[] b4 = new byte[10];
DatagramPacket dp4 = new DatagramPacket(b4, b4.length);
socket_receive.receive(dp4);
String message1 = new String(b4, 0, dp4.getLength());
if(message1.equals("star")){
byte[] b3 = intToByteArray(list.size()/2);
DatagramPacket dp3 = new DatagramPacket(b3, b3.length, InetAddress.getByName("127.0.0.1"),9000);
socket_send.send(dp3);
int index = 0;
while(index<list.size()){
String title = list.get(index++);
String answer = list.get(index++);
byte[] b1 = title.getBytes();
DatagramPacket dp1 = new DatagramPacket(b1, b1.length, InetAddress.getByName("127.0.0.1"),9000);
socket_send.send(dp1);
byte[] b2 = answer.getBytes();
DatagramPacket dp2 = new DatagramPacket(b2, b2.length, InetAddress.getByName("127.0.0.1"),9000);
socket_send.send(dp2);
byte[] b = new byte[10];
DatagramPacket dp = new DatagramPacket(b, b.length);
socket_receive.receive(dp);
String message = new String(b, 0, dp.getLength());
if(message.equals("next")&index==list.size()){
System.out.println("已是最后一题,断开连接");
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally{
socket_send.close();
socket_receive.close();
}
}
private static byte[] intToByteArray(int a) {
return new byte[] {
(byte) ((a >> 24) & 0xFF),
(byte) ((a >> 16) & 0xFF),
(byte) ((a >> 8) & 0xFF),
(byte) (a & 0xFF)
};
}
}
客户端:
package work4_3;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Optional;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Client extends Application{
BorderPane root;
Label l_title,l_timu,l_answer;
TextField text;
Button btn_star,btn_next,btn_end,btn_grade;
DatagramSocket socket_receive = null;
DatagramSocket socket_send = null;
String answer = "";
int num = 0;
int grade = 0;
int titleNum = 0;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
root = new BorderPane();
l_title = new Label("题目:");
l_timu = new Label("");
l_timu.setPrefSize(400, 80);
l_timu.setWrapText(true);
l_answer = new Label("答案:");
text = new TextField();
text.setEditable(false);
text.setFocusTraversable(false);
btn_star = new Button("开始答题");
btn_next = new Button("下一题");
btn_end = new Button("结束答题");
btn_grade = new Button("查看成绩");
VBox vbox = new VBox();
vbox.getChildren().add(l_title);
vbox.getChildren().add(l_timu);
root.setTop(vbox);
HBox hbox1 = new HBox();
hbox1.getChildren().add(l_answer);
hbox1.getChildren().add(text);
root.setCenter(hbox1);
HBox hbox = new HBox();
Label l1 = new Label();
l1.setPrefSize(40, 35);
Label l2 = new Label();
l2.setPrefSize(40, 35);
Label l3 = new Label();
l3.setPrefSize(40, 35);
Label l4 = new Label();
l4.setPrefSize(15, 35);
Label l5 = new Label();
l5.setPrefSize(20, 35);
hbox.getChildren().add(l4);
hbox.getChildren().add(btn_star);
hbox.getChildren().add(l1);
hbox.getChildren().add(btn_next);
hbox.getChildren().add(l2);
hbox.getChildren().add(btn_end);
hbox.getChildren().add(l3);
hbox.getChildren().add(btn_grade);
hbox.getChildren().add(l5);
root.setBottom(hbox);
Scene scene = new Scene(root, 400, 200);
stage.setScene(scene);
stage.show();
Platform.runLater(new Runnable() {
@Override
public void run() {
btn_star.setOnAction((ActionEvent e) ->{
text.setEditable(true);
conn();
});
btn_next.setOnAction((ActionEvent e) ->{
nextTitle();
});
btn_end.setOnAction((ActionEvent e) ->{
end();
});
btn_grade.setOnAction((ActionEvent e) ->{
lookGrade();
});
}
});
}
private void conn(){
try {
socket_receive = new DatagramSocket(9000);
socket_send = new DatagramSocket();
text.requestFocus();
text.setFocusTraversable(true);
if(socket_send!=null){
byte[] message = "star".getBytes();
try {
DatagramPacket dp = new DatagramPacket(message, message.length, InetAddress.getByName("127.0.0.1"),9001);
socket_send.send(dp);
byte[] b1 = new byte[10];
DatagramPacket dp1 = new DatagramPacket(b1, b1.length);
socket_receive.receive(dp1);
titleNum = byteArrayToInt(b1);
} catch (Exception e) {
e.printStackTrace();
}
}
titlePlan();
} catch (Exception e) {
e.printStackTrace();
}
}
private int byteArrayToInt(byte[] b) {
return b[3] & 0xFF |
(b[2] & 0xFF) << 8 |
(b[1] & 0xFF) << 16 |
(b[0] & 0xFF) << 24;
}
private void titlePlan(){
try {
if(socket_receive!=null){
byte[] b1 = new byte[100];
DatagramPacket dp1 = new DatagramPacket(b1, b1.length);
socket_receive.receive(dp1);
byte[] b2 = new byte[10];
DatagramPacket dp2 = new DatagramPacket(b2, b2.length);
socket_receive.receive(dp2);
String title = new String(b1).trim();
answer = new String(b2).trim();
l_timu.setText(title);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void nextTitle(){
String s = text.getText().trim().toString();
if(s.equals("")){
Alert alert = new Alert(AlertType.INFORMATION);
alert.titleProperty().set("提示");
alert.headerTextProperty().set("答案不得为空!");
alert.showAndWait();
}else{
byte[] message = "next".getBytes();
try {
DatagramPacket dp = new DatagramPacket(message, message.length, InetAddress.getByName("127.0.0.1"),9001);
socket_send.send(dp);
if(--titleNum==0){
Alert alert = new Alert(AlertType.INFORMATION);
alert.titleProperty().set("提示");
alert.headerTextProperty().set("已经是最后一题,请结束答题!");
alert.showAndWait();
}else{
text.setText("");
text.requestFocus();
text.setFocusTraversable(true);
num++;
if(answer.equals(s)){
grade++;
}
answer = "";
titlePlan();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void end(){
String s = text.getText().toString().trim();
if(s.equals("")){
Alert _alert = new Alert(Alert.AlertType.CONFIRMATION,"该题没有回答,是否放弃!",new ButtonType("取消", ButtonBar.ButtonData.NO),
new ButtonType("确定", ButtonBar.ButtonData.YES));
Optional<ButtonType> _buttonType = _alert.showAndWait();
if(_buttonType.get().getButtonData().equals(ButtonBar.ButtonData.YES)){
endSocket();
Alert alert = new Alert(AlertType.INFORMATION);
alert.titleProperty().set("提示");
alert.headerTextProperty().set("答题已结束,可查看成绩!");
alert.showAndWait();
}
}else{
num++;
if(answer.equals(s)){
grade++;
}
endSocket();
Alert alert = new Alert(AlertType.INFORMATION);
alert.titleProperty().set("提示");
alert.headerTextProperty().set("答题已结束,可查看成绩!");
alert.showAndWait();
}
}
private void endSocket(){
if(socket_receive!=null){
socket_receive.close();
socket_receive = null;
}
if(socket_send!=null){
socket_send.close();
socket_send = null;
}
}
private void lookGrade(){
Alert alert = new Alert(AlertType.INFORMATION);
alert.titleProperty().set("成绩");
alert.headerTextProperty().set("共回答"+num+"题,答对"+grade+"题,继续加油!");
alert.showAndWait();
}
}
这是一个简单的小程序,还有许多不简洁完善的地方,还需多多改进,仍需努力学习