La Programmazione Client/Server in Java | |||
Mar 16 Ott 2007 |
|
Introduzione
Per realizzare un programma in grado di gestire una connessione client-server in java si utilizzano le classi disponibili nel package java.net. Le classi del package java.net che si utilizzeranno sono le seguenti I metodi della classe ServerSocket che si utilizzeranno sono i seguentiMetodo | Descrizione | |
---|---|---|
Socket | accept() | Si pone in attesa di una richiesta. Arrivata la richiesta la accetta e costituisce una connessione |
void | close | Chiude la Socket. |
InetAddress | getInetAddress() | Restitisce l'indirizzo locale di questa Server Socket. |
int | getLocalPort() | Restituisce la porta a cui è in attesa la Socket. |
I metodi della classe Socket che si utilizzeranno sono i seguenti
Metodo | Descrizione | |
---|---|---|
void | close() | Chiude questa Socket. |
int | getLocalPort() | Restituisce la porta a cui è connessa la Socket. |
void | setReceiveBufferSize(int size) | Specifica la dimensione del Buffer di ricezione. |
void | setSendBufferSize(int size) | Specifica la dimensione del Buffer per l'invio dei dati. |
I costruttori di questa classe sono i seguenti
Costruttore | Descrizione |
---|---|
Socket() | Crea una Socket non connessa. |
Socket(InetAddress address, int port) | Crea una Socket e la connette alla specifica porta dello specifico indirizzo IP. |
Socket(InetAddress address, int port, InetAddress localAddr, int localPort) | Crea una Socket sulla macchina locale di cui è specificata l'indirizzo IP e la porta, e la connette con la porta remota specificata e con l'indirizzo IP specificato. |
Socket(String host, int port) | Crea una Socket e la connette con l'host il cui indirizzo è specificato da host con la porta port. |
Esempio Server
Un Server ha la struttura seguente
Server.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Server extends Thread
{
private ServerSocket Server;
public static void main(String argv[]) throws Exception
{
new Server();
}
public Server() throws Exception
{
Server = new ServerSocket(4000);
System.out.println("Il Server è in attesa sulla porta 4000.");
this.start();
}
public void run()
{
while(true)
{
try {
System.out.println("In attesa di Connessione.");
Socket client = Server.accept();
System.out.println("Connessione accettata da: "+
client.getInetAddress());
Connect c = new Connect(client);
}
catch(Exception e) {}
}
}
}
class Connect extends Thread
{
private Socket client = null;
BufferedReader in = null;
PrintStream out = null;
public Connect() {}
public Connect(Socket clientSocket)
{
client = clientSocket;
try
{
in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
out = new PrintStream(client.getOutputStream(), true);
}
catch(Exception e1)
{
try { client.close(); }
catch(Exception e) { System.out.println(e.getMessage());}
return;
}
this.start();
}
public void run()
{
try
{
out.println("Generico messaggio per il Client");
out.flush();
// chiude gli stream e le connessioni
out.close();
in.close();
client.close();
}
catch(Exception e) {}
}
}
Il server deve poter accettare richieste da più client contemporaneamente. La classe Server estendendo la classe Thread
public class Server extends Thread
realizza un multithreading, in questo modo il server è in grado di accettare richieste da più client contemporaneamente.
La costruzione del server prevede l'esecuzione dei seguenti passi
-
Si crea un oggetto ServerSocket e lo si pone in ascolto
su una determinata porta.
La classe Server implementerà il server, nel main della classe Server si crea un nuovo oggetto Server. Nel costruttore della classe Server si crea un oggetto ServerSocket che si metterà in ascolto sulla porta 4000, quindi si fa partire l'esecuzione in multithreading chiamando il metodo this.start(), che lancia il metodo run.
public Server() throws Exception
{
Server = new ServerSocket(4000);
System.out.println("Il Server è in attesa sulla porta 4000.");
this.start();
}
-
Nel metodo run vi è un ciclo infinito in cui il server è
in ascolto sulla porta 4000, ed ogni volta che riceve una richiesta crea
i canali di comunicazione per poter comunicare con il client.
Quando il server riceve una richiesta da un client crea una nuova istanza di una Socket per quel client.
while(true)
{
try
{
System.out.println("In attesa di Connessione.");
Socket client = Server.accept();
System.out.println("Connessione accettata da: "+
client.getInetAddress());
Connect c = new Connect(client);
}
catch(Exception e) {}
}
-
Una volta accettata la connessione viene creata una nuova istanza dell'oggetto
Connect. Questo oggetto viene utilizzato per creare i canali di comunicazione
tra il client ed il server. Nel costruttore di questa classe si crea il canale di
comunicazione in output
out = new PrintStream(client.getOutputStream(), true);
ed il canale di comunicazione in input
in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
in caso di errori si chiude la connessione, altrimenti viene lanciato il metodo che si occuperà della comunicazione con il server this.start().
Nell'esempio proposto ci si limita ad inviare un generico messaggio al server e subito dopo chiude i canali di comunicazione e la connessione. - Una volta conclusa la comunicazione saranno chiusi i canali di comunicazione e la connessione.
Esempio Client
Un Client ha la struttura seguente
Client.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Client
{
public static void main(String argv[])
{
BufferedReader in = null;
PrintStream out = null;
Socket socket = null;
String message;
try
{
// open a socket connection
socket = new Socket("localhost", 4000);
// Apre i canali I/O
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out = new PrintStream(socket.getOutputStream(), true);
// Legge dal server
message = in.readLine();
System.out.print("Messaggio Ricevuto : " + message);
out.close();
in.close();
}
catch(Exception e) { System.out.println(e.getMessage());}
}
}
Il client si connette al server seguendo i seguenti passi
-
Il client effettua una connessione con il server creando un nuovo oggetto
Socket
socket = new Socket("localhost", 4000);
in questo esempio si suppone che il server si trovi sulla stessa macchina del client. -
Quindi si creano i canali di comunicazione con il server
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out = new PrintStream(socket.getOutputStream(), true);
-
a questo punto si può incominciare la comunicazione con il server.
In questo esempio la comunicazione si limita alla lettura di un messaggio
da parte del client.
message = in.readLine();
System.out.print("Messaggio Ricevuto : " + message);
-
Una volta completata la comunicazione il client disalloca
le risorse impiegate: chiude i canali di comunicazione e la connessione
con il server.
out.close();
in.close();