Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Esercizio "Telegiornale" dalla raccolta degli esercizi riassuntivi in Java: Socket in TCP e programmazione concorrente
/*
* Andrea Caravano (www.andreacaravano.net)
*
* Esercizio 5: "Telegiornale"
* Descrizione: La redazione di TGJava24 ha adottato un’infrastruttura di rete che prevede un numero variabile
* di assistenti alla regia e redattori che hanno la necessità di comunicare con il giornalista in onda in tempo reale,
* per informarlo su eventuali variazioni e/o correzioni alle notizie oggetto del telegiornale.
* Si suppone che il primo client che si collega sia il giornalista in onda e tutti i successivi siano assistenti alla
* regia e redattori.
* Un possibile esempio di variazione alle notizie comunicata dai redattori può essere la seguente:
* Traffico intenso sulla A14
* A causa delle recenti manifestazioni nell’area di Bologna, un’insolita coda si è formata all’altezza del
* chilometro 721 dell’autostrada A14.
* La struttura della notizia deve includere il titolo della notizia (su una sola linea) e il testo esteso della notizia,
* multilinea. Il client del giornalista dovrà rimanere costantemente in ascolto di eventuali variazioni comunicate
* dai redattori.
*
* Sviluppare la sola 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.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
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;
public class ServerTelegiornale {
static final int PORTALISTEN = 9000;
static int contaClient = 0;
static ExecutorService esecutore = Executors.newCachedThreadPool();
static Lock mutexLettori = new ReentrantLock();
static Lock mutexScrittori = new ReentrantLock();
static Semaphore semLettura = new Semaphore(1);
static Semaphore sincro = new Semaphore(1);
static int processiDentroScrittori = 0;
static int processiDentroLettori = 0;
static TreeMap<String, List<String>> notizie = new TreeMap<>();
public static void main(String[] args) {
System.out.println("TGJava24 - REDAZIONE");
System.out.println("====================");
try (ServerSocket procServer = new ServerSocket(PORTALISTEN)) {
System.out.format("Processo server avviato con il seguente indirizzo di socket: %s%n", procServer.getLocalSocketAddress());
while (true) {
try {
Socket tempClient = procServer.accept();
contaClient++;
if (contaClient == 1) {
esecutore.execute(() -> {
try (Socket client = tempClient) {
System.out.format("Thread ID = %d - Indirizzo di socket del client: %s%n", Thread.currentThread().getId(), client.getRemoteSocketAddress());
lettore(client);
} catch (IOException e) {
System.err.format("Errore di avvio della comunicazione: %s%n", e.getMessage());
}
});
} else {
esecutore.execute(() -> {
try (Socket client = tempClient) {
System.out.format("Thread ID = %d - Indirizzo di socket del client: %s%n", Thread.currentThread().getId(), client.getRemoteSocketAddress());
scrittore(client);
} catch (IOException e) {
System.err.format("Errore di avvio della comunicazione: %s%n", e.getMessage());
}
});
}
} 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 scrittore(Socket client) {
try (BufferedReader BR = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
PrintWriter PW = new PrintWriter(new OutputStreamWriter(client.getOutputStream(), "UTF-8"), true)) {
System.out.println("Thread scrittore avviato.");
PW.println("RUOLO = Scrittore");
while (true) {
String titoloNotiziaLocale = BR.readLine();
List<String> testoNotiziaLocale = new ArrayList<>();
String singolaRiga;
do {
singolaRiga = BR.readLine();
if (singolaRiga.isEmpty() == false)
testoNotiziaLocale.add(singolaRiga);
} while (singolaRiga.isEmpty() == false);
System.out.println("Presa in carico una nuova notizia.");
PW.println("202"); // Tratto da HTTP: "Accepted"
inizioScrittura();
notizie.put(titoloNotiziaLocale, testoNotiziaLocale);
fineScrittura();
}
} catch (UnsupportedEncodingException e) {
System.out.format("Errore: codifica non supportata: %s", e.getMessage());
} 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 lettore(Socket client) {
try (BufferedReader BR = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
PrintWriter PW = new PrintWriter(new OutputStreamWriter(client.getOutputStream(), "UTF-8"), true)) {
System.out.println("Thread lettore avviato.");
PW.println("RUOLO = Lettore");
TreeMap<String, List<String>> notizieInviate = new TreeMap<>();
while (true) {
inizioLettura();
for (Map.Entry<String, List<String>> n : notizie.entrySet()) {
if (notizieInviate.containsKey(n.getKey()) == false) {
PW.println(n.getKey());
List<String> righeNotizia = n.getValue();
for (String r : righeNotizia) {
PW.println(r);
}
notizieInviate.put(n.getKey(), n.getValue());
}
}
fineLettura();
}
} catch (UnsupportedEncodingException e) {
System.out.format("Errore: codifica non supportata: %s", e.getMessage());
} 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 fineLettura() throws InterruptedException {
mutexLettori.lock();
try {
processiDentroLettori--;
if (processiDentroLettori == 0) {
sincro.release();
}
} finally {
mutexLettori.unlock();
}
}
private static void inizioLettura() throws InterruptedException {
semLettura.acquire();
mutexLettori.lock();
try {
processiDentroLettori++;
if (processiDentroLettori == 1) {
sincro.acquire();
}
} finally {
mutexLettori.unlock();
semLettura.release();
}
}
private static void inizioScrittura() throws InterruptedException {
mutexScrittori.lock();
try {
processiDentroScrittori++;
if (processiDentroScrittori == 1) {
semLettura.acquire();
}
sincro.acquire();
} finally {
mutexScrittori.unlock();
}
}
private static void fineScrittura() throws InterruptedException {
mutexScrittori.lock();
try {
sincro.release();
processiDentroScrittori--;
if (processiDentroScrittori == 0) {
semLettura.release();
}
} finally {
mutexScrittori.unlock();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment