ServerTiHoColpito.java
/* 
 * Andrea Caravano (www.andreacaravano.net) 
 * 
 * Esercizio 1: "TiHoColpito" 
 * Descrizione: Progettare un applicazione Client/Server in Java che, a seguito dell’invio, da parte del client, 
 * di una stringa di testo contenente una lettera dell’alfabeto americano e un numero, separati da un Whitespace (es: C 6), 
 * invii, in maniera casuale, una tra le due seguenti stringhe: 
 * - “Colpito!” 
 * - “Mancato, ritenta!" 
 * Prima dell’invio, validare la correttezza della struttura dati e, se non valida, inviare al client una stringa vuota. 
 * La comunicazione termina con l’invio, da parte del client, di una stringa vuota. 
 * 
 * Possibile soluzione 
 * Componente Server 
 * 
 * N.B.: L'esercizio scaturisce dalla sola fantasia dell'autore e intende rappresentare una applicazione didattica. 
 * I dettagli in esso contenuti potrebbero non essere corrispondenti alla realtà e intendono valutare le abilità nella gestione delle strutture dati proposte. 
 */

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import java.util.Scanner;

public class ServerTiHoColpito {
    static final int PORTALISTEN = 9000;
    static final String LETTEREMAIUSCOLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    static final String LETTEREMINUSCOLE = "abcdefghijklmnopqrstuvwxyz";
    static final int MAXNUMERO = 10;
    static final String[] POSSIBILISTRINGHE = {
            "Colpito!",
            "Mancato, ritenta!"
    };

    public static void main(String[] args) {
        try (ServerSocket processoServer = new ServerSocket(PORTALISTEN)) {
            System.out.format("Processo server avviato con il seguente indirizzo di socket: %s%n", processoServer.getLocalSocketAddress());
            while (true) {
                try (Socket variabileClient = processoServer.accept()) {
                    System.out.format("Processo client connesso con il seguente indirizzo di socket: %s%n", variabileClient.getRemoteSocketAddress());
                    avviaComunicazione(variabileClient);
                } catch (IOException e) {
                    System.err.format("Errore connessione con client: %s%n", e.getMessage());
                }
            }
        } catch (IOException e) {
            System.err.format("Errore lato server: %s%n", e.getMessage());
        }
    }

    private static void avviaComunicazione(Socket varClient) throws IOException {
        BufferedReader BR = new BufferedReader(new InputStreamReader(varClient.getInputStream(), "UTF-8"));
        PrintWriter PW = new PrintWriter(new OutputStreamWriter(varClient.getOutputStream(), "UTF-8"), true);
        String stringaRicevuta = BR.readLine();
        System.out.format("Ricevuto dal client la stringa: %s%n", stringaRicevuta);
        while (stringaRicevuta.isEmpty() == false) {
            Scanner S;
            try {
                S = new Scanner(stringaRicevuta);
                String letteraStr = S.next();
                char lettera = letteraStr.toCharArray()[0];
                int numero = S.nextInt();
                if (letteraStr.length() > 1)
                    throw new Exception();
                if (LETTEREMAIUSCOLE.contains(String.valueOf(lettera)) || LETTEREMINUSCOLE.contains(String.valueOf(lettera)))
                    ;
                else {
                    throw new Exception();
                }
                if (numero >= MAXNUMERO) {
                    throw new Exception();
                }
                int numeroEstratto = new Random().nextInt(1 + 1); // Non viene scelto un seme.
                // Viene definita un'istanza di classe "Random", al momento dell'estrazione.
                System.out.format("E' stato estratto il numero: %d%n", numeroEstratto);
                PW.println((numeroEstratto == 0) ? POSSIBILISTRINGHE[0] : POSSIBILISTRINGHE[1]);
            } catch (Exception e) {
                System.err.println("Errore di formattazione dei dati da parte del client. Segnalazione...");
                PW.println("");
            }
            stringaRicevuta = BR.readLine();
            System.out.format("Ricevuto dal client la stringa: %s%n", stringaRicevuta);
        }
        System.out.println("Termine della comunicazione con il client...");
    }
}