Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/emikodes/clientserver-calculator-java
Simple Client-Server calculator, written in Java.
https://github.com/emikodes/clientserver-calculator-java
calculator calculator-java client clientserver infix-notation infix-notation-calculator infix-notation-java java-parser java-server java-socket java-socket-calculator javasocket server socket-calculator socket-programming
Last synced: about 1 month ago
JSON representation
Simple Client-Server calculator, written in Java.
- Host: GitHub
- URL: https://github.com/emikodes/clientserver-calculator-java
- Owner: emikodes
- Created: 2023-02-28T08:42:56.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-03-06T11:16:48.000Z (almost 2 years ago)
- Last Synced: 2023-09-16T05:59:38.609Z (over 1 year ago)
- Topics: calculator, calculator-java, client, clientserver, infix-notation, infix-notation-calculator, infix-notation-java, java-parser, java-server, java-socket, java-socket-calculator, javasocket, server, socket-calculator, socket-programming
- Language: Java
- Homepage:
- Size: 9.77 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Java Client-Server Calculator:
---
> Simple Client-Server calculator, written in Java using sockets.
>---
## Code:
### Client:
```java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;public class ClientCalculator {
public static void main(String[] args) {
System.out.println("Connessione al server...");
try(Socket connessioneServer = new Socket("localhost",5000)){
String IPServer = connessioneServer.getRemoteSocketAddress().toString();
String IPLocale = connessioneServer.getLocalAddress().toString();
System.out.println("Connessione col server stabilita:\nIP Server remoto: " + IPServer + "\nIP Client: " + IPLocale);BufferedReader streamInput = new BufferedReader(new InputStreamReader(connessioneServer.getInputStream()));
PrintWriter invioDati = new PrintWriter(new OutputStreamWriter(connessioneServer.getOutputStream()),true);Scanner inputStreamReader = new Scanner(System.in);
System.out.println("Inserisci l'espressione da calcolare: ");
String espressioneInput = inputStreamReader.nextLine();System.out.println("Invio dell'espressione al server...");
invioDati.println(espressioneInput);System.out.println("Attesa risposta server...");
String rispostaServer = streamInput.readLine();System.out.println("Risposta server ricevuta: " + rispostaServer);
connessioneServer.close();
inputStreamReader.close();
}catch(Exception e){
//Scrive sull'error stream (Visualizzazione in colore rosso nella shell di IntelliJ)
System.err.println("Errore durante la connessione al server: " + e.getMessage());
}
}
}
```### Server:
```java
import java.io.*;
import java.net.*;
import java.util.*;public class ServerCalcolatrice{
static int portaDelServer = 5000;public static Stack reverseStack(Stack stack){
Stack reversedStack = new Stack();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 numeri= new Stack();
Stack operandi = new Stack();
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 sottrazionirispostaClient = 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());
}
}
}
```---
## Technologies Used
- **Java**
---
## Usage
Execute the **server** code **first**, than you can execute the **client** code.
Write your math expression as **strings**, in **infix-notation**.
The server will automatically **parse** the expression, and calculate the result.
Supports **[* / + - % ^]** operands (**multiply**, **divide**, **add**, **subtract**, **modulus**, **pow**).
---
## Contact
Coded by **@emikodes** - feel free to contact me!
---