Diapositiva 1 - Istituto di Calcolo e Reti ad Alte Rrestazioni

Università degli Studi della Calabria
Corso di Laurea in Ingegneria Informatica
A.A. 2010/2011
Corso di Reti di Calcolatori
Lucidi delle Esercitazioni
Raffaele Giordanelli
1
Si vuole implementare un server che gestisce scommesse sulle corse dei
cavalli.
Il server riceve le scommesse da parte di utenti client che indicano il
numero del cavallo (da 1 a 12) su cui vogliono puntare.
Le scommesse sono ricevute, tramite il protocollo TCP, sulla porta 8001
del server. Il client effettua una scommessa inviando al server la stringa
“<num_cavallo> <puntata>”, in cui <num_cavallo> è il numero del
cavallo, e <puntata> è l’ammontare in euro della scommessa.
Il server accetta le scommesse fino all’ora <ora_limite>. A tal fine un
thread del server controlla periodicamente, es. ogni minuto, l’ora del
sistema. Quando l’ora corrente raggiunge l’ora <ora_limite>, il server
deve chiudere l’accettazione delle scommesse.
Il server memorizza in un’opportuna struttura dati le scommesse
pervenute.
Scaduto il tempo utile, il server verifica il numero del cavallo vincente (a
tal proposito si può utilizzare un metodo che estrae un numero casuale da
1 a 12), e successivamente comunica a tutti gli scommettitori i vincitori e
le somme da essi vinte.
Tale comunicazione avviene tramite l’invio, sulla porta UDP 8002 di ogni
client, della stringa “Somma vinta = <somma>” per ogni scommessa
vincente.
<somma> è l’ammontare della eventuale somma vinta, corrispondente
2
alla scommessa effettuata dal client moltiplicata per 12.
import java.io.*;
import java.net.*;
import java.util.*;
class BetClient{
int serverPort;
int myPort;
InetAddress groupAddress;
InetAddress serverAddress;
Socket s;
public BetClient(InetAddress gAddress, InetAddress server, int sPort, int mP
groupAddress=gAddress;
serverAddress=server;
serverPort=sPort;
myPort=mPort;
try{
s=new Socket(serverAddress, serverPort);
} catch (IOException ioe){
System.out.println(ioe);
}
}
3
public boolean placeBet(int nCavallo, long puntata){
String e="";
try{
BufferedReader in = new BufferedReader (new
InputStreamReader (s.getInputStream()));
PrintWriter out = new PrintWriter (s.getOutputStream(),true);
String bet =nCavallo+" "+puntata;
out.println(bet);
e=in.readLine();
} catch (IOException ioe){
System.out.println(ioe);}
return e.equals("Scommessa accettata.");
}
4
public void riceviElenco(){
try{
MulticastSocket socket=new MulticastSocket(myPort);
socket.joinGroup(groupAddress);
byte[] buf=new byte[256];
DatagramPacket packet=new DatagramPacket(buf,buf.length);
socket.receive(packet);
String elenco= new String(packet.getData());
System.out.println("Elenco vincitori: ");
System.out.println(elenco);
} catch (IOException ioe){
System.out.println(ioe);
}
}
5
public static void main (String[] args){
int serverPort=8001;
int myPort=8002;
try{
InetAddress group=InetAddress.getByName("230.0.0.1");
InetAddress server=InetAddress.getByName("127.0.0.1");
BetClient client=new BetClient(group,server,serverPort,myPort);
int nCavallo=((int)(Math.random()*12))+1;
if (client.placeBet(nCavallo, 15))
client.riceviElenco();
}catch (UnknownHostException uhe){
System.out.println(uhe);}
}// main
}// BetClient
6
import java.io.*;
import java.net.*;
import java.util.*;
class BetServer{
private
private
private
private
private
HashMap scommesse;
Calendar limite;
BetAccepter accepter;
BetDenyer denyer;
int port;
public BetServer(int port, Calendar deadline){
scommesse=new HashMap();
limite=deadline;
this.port=port;
accepter=new BetAccepter(port);
accepter.start();
}
7
class BetAccepter extends Thread{
private int port;
private ServerSocket serv;
private boolean accept;
BetAccepter (int p){
try{
port=p;
serv=new ServerSocket(port);
accept=true;
} catch (IOException ioe){
System.out.println(ioe);
}
}
public void run(){
while(accept){
try{
Calendar now=Calendar.getInstance();
serv.setSoTimeout((int)(limite.getTimeInMillis()now.getTimeInMillis()));
Socket k=serv.accept();
8
BufferedReader in = new BufferedReader (new InputStreamReader
(k.getInputStream()));
PrintWriter out = new PrintWriter (k.getOutputStream(), true );
String line=in.readLine();
int pos=line.indexOf(" ");
int numCavallo=Integer.parseInt(line.substring(0,pos));
long puntata=Long.parseLong(line.substring(pos+1));
InetAddress ip=k.getInetAddress();
Scommessa s=new Scommessa(numCavallo,puntata,ip);
int key=s.getID();
scommesse.put(new Integer(key),s);
//manda ok
out.println("Scommessa accettata.");
out.close();
k.close();
System.out.println("Ricevuta scommessa "+ip+" "+numCavallo+"
"+puntata);
9
} catch (SocketTimeoutException ste){
accept=false;
System.out.println("Tempo a disposizione per le scommesse
terminato");
}// catch
catch (IOException ioe){
System.out.println(ioe);}
}//while
try{
serv.close();
} catch (IOException ioe){
System.out.println(ioe);}
}// run
}// BetAccepter
10
class BetDenyer extends Thread{
private int port;
private ServerSocket serv;
private boolean closed;
BetDenyer (int p){
try{
port=p;
serv=new ServerSocket(port);
closed=true;
} catch (IOException ioe){
System.out.println(ioe);}
}
public void reset(){
closed=false;
}
11
public void run(){
try{
while(closed){
Socket k=serv.accept();
PrintWriter out = new PrintWriter(k.getOutputStream(),true);
out.println("Scommesse chiuse");
out.close();
k.close();
System.out.println("Rifiutata scommessa");
}//while
serv.close();
} catch (IOException ioe){
System.out.println(ioe);}
}// run
}// BetDenyer
12
public void attendiChiusuraScommesse(){
try{
accepter.join();
} catch (InterruptedException ie){
System.out.println(ie);}
}
public void chiusuraScommesse(){
denyer=new BetDenyer(port);
denyer.start();
}
public void resetServer(){
denyer.reset();
}
public LinkedList controllaScommesse (int cavalloVincente){
LinkedList elenco=new LinkedList();
for (int i=0;i<=scommesse.size();i++){
Scommessa s=(Scommessa)scommesse.get(new Integer(i));
if (s.equals(new Scommessa(cavalloVincente,0,null)))
elenco.addLast(s);
}
return elenco;
}
13
public void comunicaVincitori(LinkedList vincitori, InetAddress ind, int
port){
ListIterator it=vincitori.listIterator();
try{
MulticastSocket socket=new MulticastSocket();
byte[] buf=new byte[256];
String m="";
while(it.hasNext()){
Scommessa s=(Scommessa)it.next();
m+=s.getCavallo()+" "+(s.getPuntata()*12)+"\n";
}
buf=m.getBytes();
DatagramPacket pk=new
DatagramPacket(buf,buf.length,ind,port);
socket.send(pk);
} catch (IOException ioe){
System.out.println(ioe);}
}
14
public static void main (String[] args){
int serverPort=8001;
int clientPort=8002;
try{
InetAddress multiAddress=InetAddress.getByName("230.0.0.1");
LinkedList elenco;
Calendar deadline=Calendar.getInstance();
deadline.add(Calendar.MINUTE,1);
BetServer server=new BetServer(serverPort, deadline);
server.attendiChiusuraScommesse();
server.chiusuraScommesse();
int vincente=((int)(Math.random()*12))+1;
System.out.println("E' risultato vincitore il cavallo "+vincente);
elenco=server.controllaScommesse(vincente);
server.comunicaVincitori(elenco,multiAddress,clientPort);
System.out.println("Elenco vincitori:");
System.out.println(elenco);
Thread.sleep(150000);
server.resetServer();
}
catch (InterruptedException ie){ System.out.println(ie); }
catch (UnknownHostException uhe){ System.out.println(uhe); }
}// main
}// BetServer
15
import java.net.InetAddress;
public class Scommessa {
private int ID_scommessa;
private int N_cavallo;
private long puntata;
private InetAddress scommettitore;
private static int nextID=1;
public Scommessa (int n_cavallo, long punt, InetAddress
scommett){
ID_scommessa=nextID++;
N_cavallo=n_cavallo;
puntata=punt;
scommettitore=scommett;
}
16
public boolean equals(Object o){
if (!(o instanceof Scommessa))
return false;
Scommessa s=(Scommessa)o;
return N_cavallo==s.N_cavallo;
}
public int getCavallo(){
return N_cavallo;
}
public int getID(){
return ID_scommessa;
}
public long getPuntata(){
return puntata;
}
public InetAddress getScommettitore(){
return scommettitore;
}
}
17
Si realizzi una applicazione Communicator che, installata sulle macchine
di una rete locale, consenta agli utenti delle diverse macchine di
comunicare tra loro.
Il Communicator dovrà offrire due funzionalità:
Consentire la scoperta degli altri Communicator attivi sulla rete. La
scoperta è effettuata inviando un messaggio in broadcast sulla rete e
ricevendo le risposte dei Communicator attivi.
Consentire la comunicazione con un determinato Communicator; la
comunicazione consiste nello scambio di messaggi (stringhe) mediante
il protocollo TCP.
Ogni Communicator dovrà quindi implementare un modulo Client ed un
modulo Server che operano in parallelo:
Il modulo Client consente all’utente di effettuare richieste per scoprire i
Communicator attivi e per inviare messaggi ad altri Communicator.
Il modulo Server gestisce la ricezione dei messaggi broadcast e l’invio
delle relative risposte, nonché la ricezione dei messaggi TCP e la
visualizzazione del loro contenuto.
18
Un messaggio broadcast di scoperta contiene l’indirizzo IP del
Communicator mittente e la porta TCP usata dal modulo Server dello
stesso mittente. I Communicator riceventi rispondono inviando un
messaggio TCP a quell’indirizzo ed a quella porta. Il messaggio di risposta
contiene a sua volta l’indirizzo IP e la porta TCP del Communicator che
risponde.
Per le comunicazioni in broadcast si utilizzi l’indirizzo 230.0.0.1 e la porta
2000, mentre per le comunicazione TCP ogni Communicator utilizzi una
porta scelta dall’utente.
import java.io.*;
import java.net.*;
import java.util.*;
class multicastListener extends Thread {
int mcastPort;
InetAddress remAddress;
int tcpPort;
multicastListener(int port1, int port2) {
this.mcastPort = port1;
this.tcpPort = port2;
System.out.println("ML>Porta multicast locale = "+mcastPort);
System.out.println("ML>Porta tcp locale = "+tcpPort);
}
20
public void run () {
try {
MulticastSocket mSocket = new MulticastSocket(mcastPort);
InetAddress group = InetAddress.getByName("230.0.0.1");
mSocket.joinGroup(group);
while (true) {
// Ricevo datagramma multicast
byte[] buf = new byte[50];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
mSocket.receive(packet);
remAddress = packet.getAddress();
String received = new String (packet.getData());
int i=0;
while(Character.isDigit(received.charAt(i)))i++;
int remTCPPort = Integer.parseInt(received.substring(0,i));
System.out.println("\nML>Ricevuto mcast datagram da "+
remAddress.getHostAddress()+":"+packet.getPort());
System.out.println("ML>Contenuto del datagram: "+remTCPPort);
21
// Invio messaggio via TCP solo se il datagramma multicast
// era stato inviato da un altro Communicator (non da sè stesso)
if ( !(remAddress.equals(InetAddress.getLocalHost())) || (remTCPPort!
=tcpPort)){
System.out.println("ML>Invio risposta a "+
remAddress.getHostAddress()+":"+remTCPPort);
Socket tcpSocket = new Socket(remAddress.getHostAddress()
,remTCPPort);
PrintWriter out = new PrintWriter(tcpSocket.getOutputStream(),
true);
out.println(tcpPort);
}
}
} catch (Exception ex) { System.out.println("ML>"+ex);}
}
}
22
import java.io.*;
import java.net.*;
import java.util.*;
class socketListener extends Thread {
int tcpPort;
InetAddress remAddress;
int remTCPPort;
socketListener(int port) {
this.tcpPort = port;
System.out.println("SL>Porta tcp locale = "+port);
}
23
public void run () {
try {
ServerSocket sListener = new ServerSocket(tcpPort);
while (true) {
//Ricevo messaggio risposta via TCP
Socket sock = sListener.accept();
InetAddress remAddress = sock.getInetAddress();
BufferedReader in = new BufferedReader
(new InputStreamReader(sock.getInputStream()));
String line = in.readLine();
int remTCPPort = Integer.parseInt(line);
System.out.println("\nSL>Ricevuta risposta da "+
remAddress.getHostAddress()+":"+sock.getPort());
System.out.println("SL>Stringa socket ricevuta: "+remTCPPort);
sock.close();
}
} catch (Exception ex) { System.out.println("SL>"+ex);}
}
}
24
import java.io.*;
import java.net.*;
import java.util.*;
class Communicator {
static int multicastPort;
static int socketPort;
static void sendMcastDatagram(){
try {
while(true){
byte[] buf = new byte[50];
String strBuf = "";
strBuf += socketPort;
buf = strBuf.getBytes();
InetAddress mcastAddress =
InetAddress.getByName("230.0.0.1");
MulticastSocket mSocket = new MulticastSocket();
DatagramPacket dp = new DatagramPacket(
buf, buf.length, mcastAddress, 2000);
System.out.println("\nCO>Invio datagramma multicast");
mSocket.send(dp);
Thread.sleep(20000);
}
}catch (Exception ex){ System.out.println("CO>"+ex);}
25
public static void main(String args[]) {
// Sulla porta 2000 ricevo i datagrammi multicast
// La porta per le connessioni socket è scelta dall'utente
try {
multicastPort = 2000;
socketPort = Console.readInt("porta TCP>");
multicastListener ml = new multicastListener
(multicastPort,socketPort);
socketListener sl = new socketListener(socketPort);
ml.start();
sl.start();
sendMcastDatagram();
}
catch (Exception ex) { System.out.println("CO>"+ex);}
}
}
26