Ing. Jody Marca – jody.marca@polimi.it
Laboratorio N° 5
Cosa faremo oggi
Comunicazione tramite TCP socket
Comunicazione tramite UDP socket
RIPASSO: Input Output
In Java la gestione dell’input-output è basata su stream Tutte gli stream sono figli di InputStream o OutputStream
Gli InputStream sono utilizzati per leggere da una sorgente di dati
Gli OutputStream sono utilizzati per scrivere i dati
RIPASSO: Leggere e scrivere un file
L’interazione con i file in Java deve seguire il seguente flusso:
Inizializzazione dello stream di lettura/scrittura Lettura/scrittura dei dati
Chiusura dello stream di lettura/scrittura
Socket
È il meccanismo base che permette la comunicazione tra un client ed un server.
Vi permette di creare un canale (identificato da un
indirizzo IP e una porta) su cui inviare e ricevere dati
socket
client server
TCP Socket
Il ServerSocket accetta le connessioni e crea un Socket per gestire la connessione con il client
Utilizzando il protocollo TCP ha il concetto di connessione e di gestione degli errori
Lato client Lato server
Socket ServerSocket
Socket
TCP Socket - Server di esempio
import java.io.*;
import java.net.*;
public class SimpleServer { //Porta del socket
private static final int port = 4445;
public static void main(String[] args) {
//Dichiaro le variabili per il ServerSocket e il Socket ServerSocket serverSocket = null;
Socket clientSocket = null;
PrintWriter writer = null;
BufferedReader reader = null;
try {
serverSocket = new ServerSocket(port); //Inizializzo il socket } catch (IOException e) {
System.err.println("Non posso fare listen sulla porta: "+port);
System.exit(1);
} try {
clientSocket = serverSocket.accept(); //Mi preparo ad accettare una connessione dal client } catch (IOException e) {
System.err.println("Accept fallita.");
System.exit(1);
}
TCP Socket - Server di esempio/2
try {
//Inizializzo la scrittura sul socket
writer = new PrintWriter(clientSocket.getOutputStream(), true);
//Inizializzo la lettura dal socket
reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//Leggo una stringa dal socket String stringa = reader.readLine();
System.out.println("Ricevuta stringa: "+stringa);
stringa = "Ciao "+stringa;
//Scrivo una stringa sul socket writer.write(stringa);
writer.flush();
} catch (IOException e) {
System.err.println("Errore di comunicazione.");
} finally { //Alla fine chiudo sempre il reader, il writer, il socket e il serverSocket try { reader.close(); } catch (IOException e) {e.printStackTrace();}
writer.close();
if(!clientSocket.isClosed()){
try {clientSocket.close(); } catch (IOException e) {e.printStackTrace();}
}
if(!serverSocket.isClosed()){
try { serverSocket.close();} catch (IOException e) {e.printStackTrace();}
} } } }
TCP Socket - Client di esempio
import java.io.*;
import java.net.*;
public class SimpleClient {
//Porta e indirizzo di connessione private static final int port = 4445;
private static final String host = "127.0.0.1";
public static void main(String[] args){
Socket socket = null;
PrintWriter writer = null;
BufferedReader reader = null;
try {
//Connessione al server remoto socket = new Socket(host , port);
//Inizializzo la lettura dal socket
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//Inizializzo la la scrittura sul socket
writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader inputBuffer = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Ciao come ti chiami: ");
String stringa = null;
TCP Socket - Client di esempio/2
try {
stringa = inputBuffer.readLine(); //Leggo da tastiera } catch (IOException e) {
System.err.println("Errore di lettura da tastiera");
stringa = "NO NAME";
}finally{
try { inputBuffer.close(); } catch (IOException e) { } }
writer.println(stringa); //Scrivo sul socket stringa = reader.readLine(); //Leggo dal socket System.out.println("Ricevuto dal server: " + stringa);
} catch (UnknownHostException e) {
System.err.println("Host "+host+" non conosciuto");
System.exit(1);
} catch (IOException e) {
System.err.println("Connessione a "+host+" non riuscita");
System.exit(1);
}finally{ //Alla fine chiudo sempre il reader, il writer e il socket try { reader.close(); } catch (IOException e) {}
writer.close();
if(!socket.isClosed()){
try {socket.close(); } catch (IOException e) {}
} } }}
TCP Socket – Un passo oltre
E se devo inviare degli oggetti???
Posso inviare tramite socket anche degli oggetti a patto che siano serializzabili.
Oggetto che implementa l’interfaccia Serializable
OggettoSerializzabile oggetto = new OggettoSerializzabile ();
Scrittura dell’oggetto sul socket
ObjectOutputStream objOutStream = new ObjectOutputStream(socket.getOutputStream());
objOutStream.writeObject(oggetto);
Lettura dell’oggetto dal socket
ObjectInputStream objInputStream = new ObjectInputStream(socket.getInputStream());
oggetto = (OggettoSerializzabile) objInputStream.readObject();
UDP Socket
Attenzione che il protocollo di trasmissione è UDP/IP e non TCP/IP quindi non c’è alcuna gestione degli errori e non si è sicuri che il pacchetto arrivi a destinazione
Lato client Lato server
Pacchetto UDP
Pacchetto UDP Pacchetto UDP
Socket Socket
UDP Socket - Server di esempio
import java.net.*;
//Attenzione nel seguente esempio non sono gestite le eccezioni
public class UDPServer {
//Porta del socket
private static final int port = 4444;
public static void main(String[] args) throws Exception { //Inizializzazione del Udp Socket – lato server
DatagramSocket serverSocket = new DatagramSocket(port);
byte[] receiveData = new byte[50], sendData = new byte[50]; //Buffer di invio e ricezione DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
serverSocket.receive(receivePacket); //Ricezione di un pacchetto UDP String sentence = new String(receivePacket.getData());
//Recupero l’indirizzo del client
InetAddress iPAddress = receivePacket.getAddress();
//Recupero la porta del client
int portaClient = receivePacket.getPort();
sentence = sentence.toUpperCase();
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length, iPAddress, portaClient);
serverSocket.send(sendPacket); //Invio di un pacchetto UDP serverSocket.close(); //Chiudo il socket
} }
UDP Socket - Client di esempio
import java.io.*;
import java.net.*;
//Attenzione nel seguente esempio non sono gestite le eccezioni
public class UDPClient {
//Porta del socket
private static final int port = 4444;
public static void main(String[] args) throws Exception {
BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
//Inizializzazione del Udp Socket – lato client
DatagramSocket udpSocket = new DatagramSocket();
InetAddress iPAddress = InetAddress.getLocalHost(); //Indirizzo IP Locale
byte[] sendData = new byte[50], receiveData = new byte[50]; //Buffer di invio e ricezione String stringa = consoleInput.readLine();
consoleInput.close();
sendData = stringa.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, iPAddress, port);
udpSocket.send(sendPacket); //Invio di un pacchetto UDP
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
udpSocket.receive(receivePacket); //Ricezione di un pacchetto UDP String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
udpSocket.close();
} }