-
Notifications
You must be signed in to change notification settings - Fork 0
/
ServerCalculator.java
140 lines (106 loc) · 5.89 KB
/
ServerCalculator.java
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
import java.io.*;
import java.net.*;
import java.util.*;
public class INGENITO_ServerCalcolatrice{
static int portaDelServer = 5000;
public static <T> Stack<T> reverseStack(Stack<T> stack){
Stack<T> reversedStack = new Stack<T>();
while(!stack.empty()){
reversedStack.push(stack.pop());
}
return reversedStack;
}
public static void elabora(Socket clientSocket){
try{
//InputStreamReader, utilizza una tecnica di lettura sequenziale, per cui legge dal client un byte alla volta.
//BufferedReader invece, utilizza una tecnica di "Buffering",
//per cui legge l'intera stringa in RAM (carattere per carattere, invece di leggere per bytes),
//velocizzando le future operazioni di lettura.
//BufferedReader non può leggere il buffer di input direttamente, quindi utilizziamo InputStreamReader
//come "interfaccia" per poi permettere a BufferedReader la lettura per caratteri.
BufferedReader inputStreamClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//PrintWriter permette di formattare i dati per la scrittura (partendo dai dati primitivi di Java),OutputStreamWriter è un wrapper della classe OutputStream che permette di scrivere stringhe e caratteri, al posto di bytes codificati.
PrintWriter outputStreamClient = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()),true);
//ora, possiamo utilizzare queste due interfacce per le operazioni di I/O:
System.out.println("In attesa del messaggio da parte del client...");
String messaggioClient = inputStreamClient.readLine();
System.out.println("Messaggio ricevuto: " + messaggioClient);
//Esempio possibile stringa ricevuta: 15*2-3+8/6-2
Double rispostaClient=0.0;
Stack<Double> numeri= new Stack<Double>();
Stack<Character> operandi = new Stack<Character>();
char operando;
Double num;
String[] parsedElements = messaggioClient.split("(?<=[-+*^/\\(\\)])|(?=[-+*^/\\(\\)])");
//Riempio i due stack "numeri" e "operandi", ed eseguo già divisioni e moltiplicazioni.
numeri.push(Double.parseDouble(parsedElements[0]));
for(int i=1;i<=parsedElements.length-2;i+=2){
try{
operando = parsedElements[i].toCharArray()[0];
num = Double.parseDouble(parsedElements[i+1]);
if(operando=='*'){
numeri.push(numeri.pop()*num);
}else if(operando=='/'){
numeri.push(numeri.pop()/num);
}else if(operando=='^'){
numeri.push(Math.pow(numeri.pop(),num));
}else{
numeri.push(num);
operandi.push(operando);
}
}catch(Exception e){
System.out.println("Espressione formattata male.");
}
}
numeri = reverseStack(numeri);
operandi = reverseStack(operandi);
/*System.out.println("Contenuto stack numeri:");
while(!numeri.empty()){
System.out.println(numeri.pop());
}
System.out.println("Contenuto stack operandi:");
while(!operandi.empty()){
System.out.println(operandi.pop());
}*/
//addizioni e sottrazioni
rispostaClient = numeri.pop();
while(!numeri.empty() && !operandi.empty()){
operando = operandi.pop();
num = numeri.pop();
if(operando == '+'){
rispostaClient += num;
}else if(operando == '-'){
rispostaClient -= num;
}
}
System.out.println("Invio risposta al client...");
outputStreamClient.println(rispostaClient);
System.out.println("Risposta inviata con successo.");
}catch(Exception e){
System.err.println("Errore durante l'elaborazione dei dati: " + e.getMessage());
}
}
public static void main(String args[]) {
//implementazione "portable" del paradigma client-server, è inserito in un blocco
//try-catch, perchè genera un eccezione se il server non può esser reso
//risponibile sulla porta specificata (per un qualsiasi motivo).
try(ServerSocket serverSocket = new ServerSocket(portaDelServer)){
System.out.println("Il Server è disponibile e in ascolto sulla porta: " + portaDelServer + " , IP:" + serverSocket.getLocalSocketAddress());
while(true){
//accetta richieste in entrata, in un oggetto di tipo "Socket".
try(Socket clientSocket = serverSocket.accept()){
String indirizzoIPclient = clientSocket.getRemoteSocketAddress().toString();
//memorizza l'indirizzo IP del client a cui il server è connesso, restituisce NULL se la connessione non è andata a buon fine.
System.out.println("Connesso con il client, IP: " + indirizzoIPclient);
elabora(clientSocket);
System.out.println("Chiusura connessione client.");
clientSocket.close();
}catch (Exception e){
System.err.println("Errore durante la connessione col client: " + e.getMessage());
}
}
}catch(Exception e){
System.err.println("Errore durante l'esecuzione del codice server" + e.getMessage());
}
}
}