Snippets
Andrea Caravano Esercizio "Linate" dalla raccolta degli esercizi riassuntivi in Java: Socket in TCP e programmazione concorrente
Created by
Andrea Caravano
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 | /*
* Andrea Caravano (www.andreacaravano.net)
*
* Esercizio 4: "Linate"
* Descrizione: Il recente processo di ristrutturazione dell’aeroporto di Milano Linate, ha causato un
* insolito aumento dei passeggeri nell’aeroporto, causando un incremento del numero di hostess e
* manager del check-in che, parallelamente, si occupano di modificare i dettagli di un volo in partenza.
* Nel problema proposto, le hostess sono rappresentate due Thread che operano solo quando non stanno operando i
* due altri Thread assegnati ai manager del check-in.
* Si sottolinea, tuttavia, che le hostess e i manager del check-in, possono operare contemporaneamente
* tra di loro, gestendo la modifica dei parametri del volo mediante apposite strutture di gestione della mutua esclusione.
* I dettagli del volo su cui operano i due gruppi di Thread sono i seguenti:
* 1) Località di partenza: Milano Linate
* 2) Località di arrivo: Roma Fiumicino
* 3) Data e orario del volo: 18/12/2019 – 09:50
* 4) Incremento di un unità del numero di passeggeri (numero iniziale = 0)
* Il server inizia la propria attività solo quando tutti e 4 i client sono connessi.
* Attraverso un menù di scelta (che includa anche la possibilità di chiusura della connessione), il client decide
* quale operazione attuare e lo comunica al server, che si occuperà di fornire opportuna risposta di conferma.
* Si suppone non vi siano vincoli di precedenza. Il primo gruppo di processi che viene avviato, da avvio alle
* operazioni di modifica.
*
* Possibile soluzione
* Componente Client
*
* 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.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
class Volo {
public String localitaPartenza, localitaArrivo, dataVolo;
public int numeroPasseggeri;
Volo(String localitaPartenza, String localitaArrivo, String dataVolo, int numeroPasseggeri) {
this.localitaPartenza = localitaPartenza;
this.localitaArrivo = localitaArrivo;
this.dataVolo = dataVolo;
this.numeroPasseggeri = numeroPasseggeri;
}
}
public class ClientLinate {
static final String INDIRIZZOSERVER = "127.0.0.1";
static final int PORTASERVER = 9000;
public static void main(String[] args) {
try (Socket processoClient = new Socket(INDIRIZZOSERVER, PORTASERVER)) {
System.out.format("Connesso al processo server avviato con il seguente indirizzo di socket: %s%n", processoClient.getRemoteSocketAddress());
System.out.format("Processo client avviato con il seguente indirizzo di socket: %s%n", processoClient.getLocalSocketAddress());
avviaComunicazione(processoClient);
} catch (UnknownHostException e) {
System.err.println("Server non contattabile. Possibile errore di immissione.");
} catch (IOException e) {
System.err.format("Errore connessione con server: %s%n", e.getMessage());
}
}
private static void avviaComunicazione(Socket processoClient) throws IOException {
BufferedReader BR = new BufferedReader(new InputStreamReader(processoClient.getInputStream(), "UTF-8"));
PrintWriter PW = new PrintWriter(new OutputStreamWriter(processoClient.getOutputStream(), "UTF-8"), true);
Scanner S = new Scanner(System.in);
System.out.println("AEROPORTO DI MILANO LINATE");
System.out.println("==========================");
System.out.println();
System.out.println("In attesa di iniziare la propria attività...");
System.out.println();
System.out.println("Benvenuto!");
while (BR.readLine().equals("100")) {
System.out.println();
System.out.println("Di seguito, le possibili scelte: ");
System.out.println("1) Modifica della località di partenza");
System.out.println("2) Modifica della località di arrivo");
System.out.println("3) Modifica dell'orario del volo");
System.out.println("4) Aggiunta di un passeggero");
System.out.println("5) Esci");
System.out.println();
System.out.print("Scelta: ");
int scelta = S.nextInt();
S.nextLine();
PW.println(scelta);
String risposta = BR.readLine();
if (risposta.equals("405")) {
System.err.println("Metodo non consentito. Chiusura della comunicazione...");
break;
} else if (risposta.equals("100")) {
if (scelta == 1) {
System.out.print("Inserisci la nuova località di partenza: ");
PW.println(S.nextLine());
} else if (scelta == 2) {
System.out.print("Inserisci la nuova località di arrivo: ");
PW.println(S.nextLine());
} else if (scelta == 3) {
System.out.print("Inserisci la nuova data del volo: ");
PW.println(S.nextLine());
}
risposta = BR.readLine();
if (risposta.equals("200")) {
System.out.println("Modifica accettata.");
} else if (risposta.equals("202") && scelta == 5) {
System.out.println("Richiesta di chiusura della comunicazione accettata.");
break;
}
} else
System.err.println("Errore nella comunicazione.");
}
}
}
|
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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | /*
* Andrea Caravano (www.andreacaravano.net)
*
* Esercizio 4: "Linate"
* Descrizione: Il recente processo di ristrutturazione dell’aeroporto di Milano Linate, ha causato un
* insolito aumento dei passeggeri nell’aeroporto, causando un incremento del numero di hostess e
* manager del check-in che, parallelamente, si occupano di modificare i dettagli di un volo in partenza.
* Nel problema proposto, le hostess sono rappresentate due Thread che operano solo quando non stanno operando i
* due altri Thread assegnati ai manager del check-in.
* Si sottolinea, tuttavia, che le hostess e i manager del check-in, possono operare contemporaneamente
* tra di loro, gestendo la modifica dei parametri del volo mediante apposite strutture di gestione della mutua esclusione.
* I dettagli del volo su cui operano i due gruppi di Thread sono i seguenti:
* 1) Località di partenza: Milano Linate
* 2) Località di arrivo: Roma Fiumicino
* 3) Data e orario del volo: 18/12/2019 – 09:50
* 4) Incremento di un unità del numero di passeggeri (numero iniziale = 0)
* Il server inizia la propria attività solo quando tutti e 4 i client sono connessi.
* Attraverso un menù di scelta (che includa anche la possibilità di chiusura della connessione), il client decide
* quale operazione attuare e lo comunica al server, che si occuperà di fornire opportuna risposta di conferma.
* Si suppone non vi siano vincoli di precedenza. Il primo gruppo di processi che viene avviato, da avvio alle
* operazioni di modifica.
*
* 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.net.SocketTimeoutException;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Volo {
public String localitaPartenza, localitaArrivo, dataVolo;
public int numeroPasseggeri;
Volo(String localitaPartenza, String localitaArrivo, String dataVolo, int numeroPasseggeri) {
this.localitaPartenza = localitaPartenza;
this.localitaArrivo = localitaArrivo;
this.dataVolo = dataVolo;
this.numeroPasseggeri = numeroPasseggeri;
}
public void stampaInfoVolo() {
System.out.println("Informazioni sul volo:");
System.out.format("\tLocalità di partenza: %s%n", localitaPartenza);
System.out.format("\tLocalità di arrivo: %s%n", localitaArrivo);
System.out.format("\tData del volo: %s%n", dataVolo);
System.out.format("\tNumero di passeggeri: %s%n", numeroPasseggeri);
}
}
public class ServerLinate {
static final int PORTALISTEN = 9000;
static ExecutorService esecutore = Executors.newCachedThreadPool();
static final int TEMPOCONTROLLO = 5000;
static final int MINCLIENT = 4;
static boolean aspettaClient = true;
static int processiAvviati = 0;
static CountDownLatch cdlAvvio = new CountDownLatch(1);
static Lock mutexManager = new ReentrantLock();
static Lock mutexHostess = new ReentrantLock();
static Semaphore mutex = new Semaphore(1);
static Lock mutexVariazioni = new ReentrantLock();
static int processiDentroGruppoManager = 0;
static int processiDentroGruppoHostess = 0;
static Volo volo = new Volo("Milano Linate", "Roma Fiumicino", "18/12/2019 - 09:50", 0);
public static void main(String[] args) {
try (ServerSocket procServer = new ServerSocket(PORTALISTEN)) {
procServer.setSoTimeout(5000);
System.out.format("Processo server avviato con il seguente indirizzo di socket: %s%n", procServer.getLocalSocketAddress());
while (aspettaClient) {
try {
Socket tempSocket = procServer.accept();
processiAvviati++;
if (processiAvviati <= MINCLIENT / 2) {
esecutore.execute(() -> {
try (Socket varClient = tempSocket) {
System.out.format("Thread ID = %d - Indirizzo di socket del client: %s%n", Thread.currentThread().getId(), varClient.getRemoteSocketAddress());
manager(varClient);
} catch (IOException e) {
System.err.format("Errore di avvio della comunicazione: %s%n", e.getMessage());
}
});
} else {
esecutore.execute(() -> {
try (Socket varClient = tempSocket) {
System.out.format("Thread ID = %d - Indirizzo di socket del client: %s%n", Thread.currentThread().getId(), varClient.getRemoteSocketAddress());
hostess(varClient);
} catch (IOException e) {
System.err.format("Errore di avvio della comunicazione: %s%n", e.getMessage());
}
});
}
} catch (SocketTimeoutException e) {
if (processiAvviati >= MINCLIENT) {
aspettaClient = false;
cdlAvvio.countDown();
} else {
System.err.println("Ancora non è stato raggiunto il numero di client minimo.");
}
} catch (IOException e) {
System.err.format("Errore nella creazione di nuovi socket: %s%n", e.getMessage());
}
}
} catch (IOException e) {
System.err.format("Errore lato server: %s%n", e.getMessage());
}
}
private static void manager(Socket varClient) {
try (
BufferedReader BR = new BufferedReader(new InputStreamReader(varClient.getInputStream(), "UTF-8"));
PrintWriter PW = new PrintWriter(new OutputStreamWriter(varClient.getOutputStream(), "UTF-8"), true)
) {
cdlAvvio.await();
mutexManager.lock();
try {
processiDentroGruppoManager++;
if (processiDentroGruppoManager == 1) {
mutex.acquire();
}
System.out.format("Il manager n. %d ha avviato la propria attività%n", processiDentroGruppoManager);
} finally {
mutexManager.unlock();
}
PW.println("100"); // Tratto da HTTP: "Continue"
comunica(BR, PW);
mutexManager.lock();
try {
processiDentroGruppoManager--;
if (processiDentroGruppoManager == 0) {
mutex.release();
}
} finally {
mutexManager.unlock();
}
} catch (IOException e) {
System.err.format("Errore di I/O: %s%n", e.getMessage());
} catch (InterruptedException e) {
System.err.format("Errore di gestione dei meccanismi della programmazione concorrente: %s%n", e.getMessage());
}
}
private static void hostess(Socket varClient) {
try (
BufferedReader BR = new BufferedReader(new InputStreamReader(varClient.getInputStream(), "UTF-8"));
PrintWriter PW = new PrintWriter(new OutputStreamWriter(varClient.getOutputStream(), "UTF-8"), true)
) {
cdlAvvio.await();
mutexHostess.lock();
try {
processiDentroGruppoHostess++;
if (processiDentroGruppoHostess == 1) {
mutex.acquire();
}
System.out.format("La hostess n. %d ha avviato la propria attività%n", processiDentroGruppoHostess);
} finally {
mutexHostess.unlock();
}
PW.println("100"); // Tratto da HTTP: "Continue"
comunica(BR, PW);
mutexHostess.lock();
try {
processiDentroGruppoHostess--;
if (processiDentroGruppoHostess == 0) {
mutex.release();
}
} finally {
mutexHostess.unlock();
}
} catch (IOException e) {
System.err.format("Errore di I/O: %s%n", e.getMessage());
} catch (InterruptedException e) {
System.err.format("Errore di gestione dei meccanismi della programmazione concorrente: %s%n", e.getMessage());
}
}
private static void comunica(BufferedReader BR, PrintWriter PW) throws IOException {
int scelta = new Scanner(BR.readLine()).nextInt();
while (true) {
if (scelta == 1) {
PW.println("100");
mutexVariazioni.lock();
try {
volo.localitaPartenza = BR.readLine();
PW.println("200"); // Tratto da HTTP: "OK"
} finally {
mutexVariazioni.unlock();
}
} else if (scelta == 2) {
PW.println("100");
mutexVariazioni.lock();
try {
volo.localitaArrivo = BR.readLine();
PW.println("200");
} finally {
mutexVariazioni.unlock();
}
} else if (scelta == 3) {
PW.println("100");
mutexVariazioni.lock();
try {
volo.dataVolo = BR.readLine();
PW.println("200");
} finally {
mutexVariazioni.unlock();
}
} else if (scelta == 4) {
PW.println("100");
mutexVariazioni.lock();
try {
volo.numeroPasseggeri++;
PW.println("200");
} finally {
mutexVariazioni.unlock();
}
} else if (scelta == 5) {
PW.println("100"); // Tratto da HTTP: "Continue"
PW.println("202"); // Tratto da HTTP: "Accepted"
break;
} else {
PW.println("405"); // Tratto da HTTP: "Method not allowed"
}
volo.stampaInfoVolo();
PW.println("100");
scelta = new Scanner(BR.readLine()).nextInt();
}
}
}
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.