{"id":24033349,"url":"https://github.com/emikodes/clientserver-calculator-java","last_synced_at":"2025-02-26T04:41:26.659Z","repository":{"id":195009086,"uuid":"607572278","full_name":"emikodes/ClientServer-Calculator-Java","owner":"emikodes","description":"Simple Client-Server calculator, written in Java.","archived":false,"fork":false,"pushed_at":"2023-03-06T11:16:48.000Z","size":10,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-08T18:18:53.575Z","etag":null,"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"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emikodes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-02-28T08:42:56.000Z","updated_at":"2023-02-28T08:49:56.000Z","dependencies_parsed_at":"2023-09-16T05:59:43.485Z","dependency_job_id":null,"html_url":"https://github.com/emikodes/ClientServer-Calculator-Java","commit_stats":null,"previous_names":["emikodes/clientserver-calculator-java"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emikodes%2FClientServer-Calculator-Java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emikodes%2FClientServer-Calculator-Java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emikodes%2FClientServer-Calculator-Java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emikodes%2FClientServer-Calculator-Java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emikodes","download_url":"https://codeload.github.com/emikodes/ClientServer-Calculator-Java/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240794937,"owners_count":19858719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["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"],"created_at":"2025-01-08T18:19:09.553Z","updated_at":"2025-02-26T04:41:26.627Z","avatar_url":"https://github.com/emikodes.png","language":"Java","readme":"# Java Client-Server Calculator:\n\n---\n\n\u003e Simple Client-Server calculator, written in Java using sockets.\n\u003e \n\n---\n\n## Code:\n\n### Client:\n\n```java\nimport java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.io.OutputStreamWriter;\nimport java.io.PrintWriter;\nimport java.net.Socket;\nimport java.util.Scanner;\n\npublic class ClientCalculator {\n    public static void main(String[] args) {\n            System.out.println(\"Connessione al server...\");\n            try(Socket connessioneServer = new Socket(\"localhost\",5000)){\n                String IPServer = connessioneServer.getRemoteSocketAddress().toString();\n                String IPLocale = connessioneServer.getLocalAddress().toString();\n                System.out.println(\"Connessione col server stabilita:\\nIP Server remoto: \" + IPServer + \"\\nIP Client: \" + IPLocale);\n\n                BufferedReader streamInput = new BufferedReader(new InputStreamReader(connessioneServer.getInputStream()));\n                PrintWriter invioDati = new PrintWriter(new OutputStreamWriter(connessioneServer.getOutputStream()),true);\n\n                Scanner inputStreamReader = new Scanner(System.in);\n\n                System.out.println(\"Inserisci l'espressione da calcolare: \");\n                String espressioneInput = inputStreamReader.nextLine();\n\n                System.out.println(\"Invio dell'espressione al server...\");\n                invioDati.println(espressioneInput);\n\n                System.out.println(\"Attesa risposta server...\");\n                String rispostaServer = streamInput.readLine();\n\n                System.out.println(\"Risposta server ricevuta: \" + rispostaServer);\n            \n                connessioneServer.close();\n                inputStreamReader.close();\n            }catch(Exception e){\n                //Scrive sull'error stream (Visualizzazione in colore rosso nella shell di IntelliJ)\n                System.err.println(\"Errore durante la connessione al server: \" + e.getMessage());\n            }\n    }\n}\n```\n\n### Server:\n\n```java\nimport java.io.*;\nimport java.net.*;\nimport java.util.*;\n\npublic class ServerCalcolatrice{\n    static int portaDelServer = 5000;\n\n    public static \u003cT\u003e Stack\u003cT\u003e reverseStack(Stack\u003cT\u003e stack){\n        Stack\u003cT\u003e reversedStack = new Stack\u003cT\u003e();\n\n        while(!stack.empty()){\n            reversedStack.push(stack.pop());\n        }\n\n        return reversedStack;\n    }\n\n    public static void elabora(Socket clientSocket){\n        try{\n            //InputStreamReader, utilizza una tecnica di lettura sequenziale, per cui legge dal client un byte alla volta.\n            //BufferedReader invece, utilizza una tecnica di \"Buffering\",\n            //per cui legge l'intera stringa in RAM (carattere per carattere, invece di leggere per bytes),\n            //velocizzando le future operazioni di lettura.\n            //BufferedReader non può leggere il buffer di input direttamente, quindi utilizziamo InputStreamReader\n            //come \"interfaccia\" per poi permettere a BufferedReader la lettura per caratteri.\n            BufferedReader inputStreamClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));\n\n            //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.\n            PrintWriter outputStreamClient = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()),true);\n\n            //ora, possiamo utilizzare queste due interfacce per le operazioni di I/O:\n\n            System.out.println(\"In attesa del messaggio da parte del client...\");\n            String messaggioClient = inputStreamClient.readLine();\n\n            System.out.println(\"Messaggio ricevuto: \" + messaggioClient);\n\n            //Esempio possibile stringa ricevuta: 15*2-3+8/6-2\n\n            Double rispostaClient=0.0;\n            Stack\u003cDouble\u003e numeri= new Stack\u003cDouble\u003e();\n            Stack\u003cCharacter\u003e operandi = new Stack\u003cCharacter\u003e();\n            \n            char operando;\n            Double num;\n\n            String[] parsedElements = messaggioClient.split(\"(?\u003c=[-+*^/\\\\(\\\\)])|(?=[-+*^/\\\\(\\\\)])\");            \n\n            //Riempio i due stack \"numeri\" e \"operandi\", ed eseguo già divisioni e moltiplicazioni.\n            numeri.push(Double.parseDouble(parsedElements[0]));\n\n                    for(int i=1;i\u003c=parsedElements.length-2;i+=2){\n                        try{\n                            operando = parsedElements[i].toCharArray()[0];\n                            num = Double.parseDouble(parsedElements[i+1]);\n\n                            if(operando=='*'){\n                                numeri.push(numeri.pop()*num);\n                            }else if(operando=='/'){\n                                numeri.push(numeri.pop()/num);\n                            }else if(operando=='^'){\n                                numeri.push(Math.pow(numeri.pop(),num));\n                            }else{\n                                numeri.push(num);\n                                operandi.push(operando);\n                            }\n                        }catch(Exception e){\n                            System.out.println(\"Espressione formattata male.\");\n                        }\n                    }\n            \n            numeri = reverseStack(numeri);\n            operandi = reverseStack(operandi);\n\n            /*System.out.println(\"Contenuto stack numeri:\");\n            while(!numeri.empty()){\n                System.out.println(numeri.pop());\n            }\n\n            System.out.println(\"Contenuto stack operandi:\");\n            while(!operandi.empty()){\n                System.out.println(operandi.pop());\n            }*/\n            \n            //addizioni e sottrazioni\n\n            rispostaClient = numeri.pop();\n\n            while(!numeri.empty() \u0026\u0026 !operandi.empty()){\n                operando = operandi.pop();\n                num = numeri.pop();\n                if(operando == '+'){\n                    rispostaClient += num;\n                }else if(operando == '-'){\n                    rispostaClient -= num;\n                }\n            }\n\n            System.out.println(\"Invio risposta al client...\");\n            outputStreamClient.println(rispostaClient);\n\n            System.out.println(\"Risposta inviata con successo.\");\n\n        }catch(Exception e){\n            System.err.println(\"Errore durante l'elaborazione dei dati: \" + e.getMessage());\n        }\n\n    }\n\n    public static void main(String args[]) {\n\n        //implementazione \"portable\" del paradigma client-server, è inserito in un blocco\n        //try-catch, perchè genera un eccezione se il server non può esser reso\n        //risponibile sulla porta specificata (per un qualsiasi motivo).\n        try(ServerSocket serverSocket = new ServerSocket(portaDelServer)){\n            System.out.println(\"Il Server è disponibile e in ascolto sulla porta: \" + portaDelServer + \" , IP:\" + serverSocket.getLocalSocketAddress());\n\n            while(true){\n                //accetta richieste in entrata, in un oggetto di tipo \"Socket\".\n                try(Socket clientSocket = serverSocket.accept()){\n                    String indirizzoIPclient = clientSocket.getRemoteSocketAddress().toString();\n                    //memorizza l'indirizzo IP del client a cui il server è connesso, restituisce NULL se la connessione non è andata a buon fine.\n\n                    System.out.println(\"Connesso con il client, IP: \" + indirizzoIPclient);\n\n                    elabora(clientSocket);\n\n                    System.out.println(\"Chiusura connessione client.\");\n                    clientSocket.close();\n                }catch (Exception e){\n                    System.err.println(\"Errore durante la connessione col client: \" + e.getMessage());\n                }\n\n            }\n\n        }catch(Exception e){\n            System.err.println(\"Errore durante l'esecuzione del codice server\" + e.getMessage());\n        }\n    }\n}\n```\n\n---\n\n## Technologies Used\n\n- **Java**\n\n---\n\n## Usage\n\nExecute the **server** code **first**, than you can execute the **client** code.\n\nWrite your math expression as **strings**, in **infix-notation**.\n\nThe server will automatically **parse** the expression, and calculate the result.\n\nSupports **[* / + - % ^]** operands (**multiply**, **divide**, **add**, **subtract**, **modulus**, **pow**).\n\n---\n\n## Contact\n\nCoded by **@emikodes** - feel free to contact me!\n\n---\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femikodes%2Fclientserver-calculator-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femikodes%2Fclientserver-calculator-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femikodes%2Fclientserver-calculator-java/lists"}