Skip to content

emikodes/ClientServer-Calculator-Java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 

Repository files navigation

Java Client-Server Calculator:


Simple Client-Server calculator, written in Java using sockets.


Code:

Client:

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:

import java.io.*;
import java.net.*;
import java.util.*;

public class 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());
        }
    }
}

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!


pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy