-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClientHandler.java
More file actions
142 lines (115 loc) · 6.08 KB
/
Copy pathClientHandler.java
File metadata and controls
142 lines (115 loc) · 6.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.SimpleDateFormat;
public class ClientHandler extends Thread {
private Socket socket;
//Μεταβλητές κάταστασης ανά πελάτη
private int requestCount = 0; //Πλήθος αιτημάτων
private double lastResult = 0.0; //Τελευταίο αποτέλασμα
private List<String> history = new ArrayList<>(); //Λίστα ιστορικού στη μνήμη
private static final int K = 5; //Μέγεθος ιστορικού (τελευταίες 5 εντολές)
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (
//Ανάγνωση και εγγραφή δεδομένων μέσω του Socket
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
) {
String inputLine;
//Διάβασμα εντολών, βρόγχος μέχρι ο χρήστης να τον σπάσει με εντολή
while ((inputLine = in.readLine()) != null) {
//Καταγραφή στο server.log
logRequest(socket.getInetAddress().toString(), inputLine);
//Επεξεργασία εντολής και δημιουργεία απάντησης
String response = processCommand(inputLine);
out.println(response); //Εμφάνιση απάντησης
//Τερματισμός σύνδεσης/while loop με εντολή BYE
if (response.equals("BYE")) {
break;
}
}
} catch (IOException e) {
System.out.println("Ο πελάτης αποσυνδέθηκε βίαια.");
} finally {
try { socket.close(); } catch (IOException e) {}
}
}
//Επεξεργασία εντολών
private String processCommand(String command) {
//Έλεγχος εντολής
if (command == null || command.trim().isEmpty()) return "ERROR Δεν υπάρχει εντολή";
requestCount++; //Αύξηση μετρητή αιτημάτων
addToHistory(command); //Προσθήκη εντολής στο ιστορικό
//Κάθε εντολή έχει το πρώτο κομμάτι που είναι γράμματα και μετά αν είναι αριθμιτική πράξη τους αριθμούς
//Χρήση split για να πάρουμε το κομμάτη της εντολής και του αριθμούς
String[] parts = command.trim().split("\\s+");
String cmd = parts[0].toUpperCase();
try {
switch (cmd) {
case "ADD":
if (parts.length < 3) return "ERROR Usage: ADD x y";
lastResult = Double.parseDouble(parts[1]) + Double.parseDouble(parts[2]);
return "OK " + lastResult;
case "SUB":
if (parts.length < 3) return "ERROR Usage: SUB x y";
lastResult = Double.parseDouble(parts[1]) - Double.parseDouble(parts[2]);
return "OK " + lastResult;
case "MUL":
if (parts.length < 3) return "ERROR Usage: MUL x y";
lastResult = Double.parseDouble(parts[1]) * Double.parseDouble(parts[2]);
return "OK " + lastResult;
case "DIV":
if (parts.length < 3) return "ERROR Usage: DIV x y";
double div2 = Double.parseDouble(parts[2]);
if (div2 == 0) return "ERROR Division by zero";
lastResult = Double.parseDouble(parts[1]) / div2;
return "OK " + lastResult;
case "POW":
if (parts.length < 3) return "ERROR Usage: POW x y";
lastResult = Math.pow(Double.parseDouble(parts[1]), Double.parseDouble(parts[2]));
return "OK " + lastResult;
case "LAST":
return "OK " + lastResult;
case "COUNT":
return "OK " + requestCount;
case "HIST":
return "OK History: " + history.toString();
case "HELP":
return "OK Commands: ADD, SUB, MUL, DIV, POW, LAST, COUNT, HIST, EXIT";
case "EXIT":
return "BYE";
default:
return "ERROR Unknown command";
}
} catch (NumberFormatException e) {
return "ERROR Invalid numbers";
} catch (Exception e) {
return "ERROR " + e.getMessage();
}
}
//Ιστορικό
private void addToHistory(String cmd) {
//Λίστα FIFO οπότε αν περάσει τις Κ=5 εγγραφές το παλαιότερο στοιχείο σβήνεται
if (history.size() >= K) {
history.remove(0);
}
history.add(cmd);
}
//Καταγραφή των αιτημάτων με synchronized ώστε αν την ιδια στιγμή υπάρξουν 2 αιτήματα να μην καταχωρηθουν σε μία γραμμή
private synchronized void logRequest(String ip, String cmd) {
//Τρέχουσα ώρα
String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
//Formating στο κέιμενο που θα καταγραφεί
String logEntry = timeStamp + " | IP: " + ip + " | CMD: " + cmd;
//Γράψιμο στο αρχείο με append mode
try (PrintWriter logWriter = new PrintWriter(new FileWriter("server.log", true))) {
logWriter.println(logEntry);
} catch (IOException e) {
System.err.println("Σφάλμα εγγραφής στο log: " + e.getMessage());
}
}
}