Strumenti Utente

Strumenti Sito


informatica:sol:laboratorio16:esercitazionib:esercitazione9

Esercizi Pipe/Socket

Esercizio 1: Ampiezza della pipe

Utilizzare la funzione fpathconf come nell'esempio visto a lezione per stabilire l'ampiezza minima garantita POSIX di una pipe e la sua ampiezza reale.

Esercizio 2: read() e write() bloccanti e sincronizzazione su pipe

Utilizzando le pipe senza nome, realizzare un programma C in cui il processo padre legge da standard input un intero, poi attende 5 secondi mentre figlio si blocca in attesa di una comunicazione da parte del padre, stampa il messaggio ricevuto e termina.

Modificare il programma in modo che il padre attenda 5 secondi effettui N write() di 1024 byte tutti contenenti il carattere 'r' sulla pipe mentre il figlio appena attivato attende 500 secondi prima di effettuare la read(). Per quale valore di N il padre si blocca ?

Cosa succede al padre nel programma precedente se il figlio termina immediatamente dopo essere stato avviato senza fare la read?

Esercizio 3: Produttore e consumatore con pipe

Scrivere un programma C che implementi un processo produttore che genera N numeri casuali, li passa ad un processo consumatore usando una pipe senza nome e poi termina. Il consumatore deve stampare ciascun numero ricevuto sullo standard output e terminare a sua volta alla terminazione del produttore.

Esercizio 4: who_sort_cat

Scrivere un programma C che utilizzando pipe senza nome e la duplicazione di descrittori implementa il pipeline di shell

bash:~$ who | sort | cut -b 1-10

per stampare la lista di utenti connessi. Ogni comando deve girare in un processo diverso.

Elaborazione: Usare wc -l al posto di cut per avere il numero di connessioni.

Esercizio 5: Un server ed un client

Realizzare un processo server ed un processo client. I due processi intergiscono utilizzando due pipe con nome: clientserver e clientp. Il server crea la pipe clientserver (se non esiste), la apre e si mette in attesa di messaggi da parte del client. Ogni messaggio è costituito da un double. Per ogni messaggio ricevuto x, il server calcola x*x e invia il risultato su clientp. La sequenza di messaggi termina quando il client chiude la pipe clientserver. Le pipe devono essere rimosse dal file system alla terminazione dei due processi.

Esercizio 6: Un server e molti client

Realizzare un processo server che rimane sempre attivo in attesa di richieste da parte di un insieme (possibilmente vuoto) di processi client. Ogni client richiede al server la trasformazione di tutti i caratteri minuscoli di una stringa in caratteri maiuscoli (es tigre –>TIGRE) con un messaggio su una pipe dal nome fissato: clientserver. In questo caso i messaggi sulla pipe clientserver sono scritti da processi client diversi. Ogni client prima di inviare una richiesta crea una pipe di ascolto dal nome unico (eg. usando il PID) e codifica tale nome nel messaggio inviato al server. All sua attivazione il server crea la pipe clientserver (se non esiste), la apre e si mette in attesa di messaggi da parte dei client. Ogni messaggio è costituito da una stringa e dal nome della pipe di risposta clientpid. Per ogni messaggio ricevuto il server estrae la stringa, trasforma le minuscole in maiuscole e invia il risultato su clientpid. Il server deve rimanere sempre attivo, anche alla terminazione di tutti i processi client.
Tutte le pipe devono essere rimosse dal file system alla terminazione del processo/i che le utilizzano.

Esercizio 7: Un server e molti client (multithreaded con socket)

Creare un server che utilizzi le socket AF_UNIX e piu' thread concorrenti per gestire un numero di client. Ogni client all'avvio decide quanti messeggi inviare (casualmente fra 1 e N_MSG_MAX). Tutti i messaggi inviati contengono il PID del processo client che li invia. Il srever stampa tutti i messaggi ricevuti sullo standard output.

Il server e' realizzato usando piu' thread. Un thread dispatcher che accetta le connessioni dai vari client e un thread worker per ogni client. Il thread worker viene attivato appena la connessione si stabilisce e si occupa di leggere i messaggi del client e stamparli sullo stdout. Quando il client termina l'invio (EOF) il thread worker corrispondente termina e libera la memoria occupata.

Elaborazione: Invece di attivare un thread worker per ogni client attivare un pool di worker all'inizio e schedulare le richieste arrivate sul pool in modo da bilanciare il carico dei vari worker.

Esercizio 8: Un server e molti client (single thread)

Realizzare un server ed un client analoghi a quelli dell'esercizio 5 senza usare i therad. Utilizzare la select per risolvere il non determinismo fra l'accettazione di nuove connessioni e la lettura dei messaggi dai client gia' connessi.

Esercizio 9: Big and little endians

Scrivere un programma che converte il numero esadecimale 0x3A4C rappresentato su due byte in network byte order e stampa il valore dei due byte da quello di indirizzo minore. Riconvertire il risultato in host byte order e stampare ancora i due byte a partire da quello di indirizzo minore.

Esercizio 10: Get HTTP

Scrivere un programma C che scarica la home page dal server 131.114.3.24 inviando una richiesta

#define REQUEST "GET / HTTP/1.0\r\n\r\n"

sulla porta 80.

Elaborazione: Utilizzare getaddrinfo per ottenere l'indirizzo per il server web di google in italia (“www.google.it”)

informatica/sol/laboratorio16/esercitazionib/esercitazione9.txt · Ultima modifica: 20/04/2016 alle 11:01 (8 anni fa) da Susanna Pelagatti