exercicis sockets iii

Upload: mapf55

Post on 14-Jan-2016

214 views

Category:

Documents


0 download

DESCRIPTION

sockets

TRANSCRIPT

Exercicis Sockets III:

1. El mtode isReachable de InetAddress prova si podem arribar a un dispositiu a la xarxa. Es a dir, si podem comunicar-nos amb ell per IP (si li podem enviar paquets IP).

public boolean isReachable(int timeout) throws IOExceptionpublic boolean isReachable(NetworkInterface interface, int ttl, int timeout) throws IOException

La comanda ping permet determinar si un ordinador est funcionant i si s'hi pot arribar des d'una xarxa concreta amb l'ordinador des d'on es fa la prova.

Es demana que simuleu amb un programa Java la funcionalitat de la comanda ping. Es a dir, fer un programa al qual se li passa per parmetre la IP dun ordinador i ens diu si aquest ordinador est funcionant i/o si podem arribar a ell.

Soluci:

package isReachable;

import java.net.*;

public class IsReachable {public static void main(String[] args) {try {//InetAddress direccio = InetAddress.getByName("192.168.1.26");//InetAddress direccio = InetAddress.getByName("8.8.8.8");InetAddress direccio = InetAddress.getByName("www.ies-sabadell.cat");

// intenta arribar a l'adrea durant un temps especific (timeout).// Si no ho aconsegueix retorna falseboolean reachable = direccio.isReachable(100000);

System.out.println("Podem arribar a l'ordinador? " + reachable);} catch (Exception e) {e.printStackTrace();}}}

Errors: isReachable()funciona de diferent manera a Windows i a Linux. Si a Linux no funciona podeu provar executant Eclipse amb permisos dadministrador (root).

Per veure informaci al respecte: De http://bordet.blogspot.ca/2006/07/icmp-and-inetaddressisreachable.html: ... there are many differences between the Windows and the Linux/Unix implementation of java.net.InetAddress.isReachable().

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4921816

2. Les llistes negres DNS (DNS blacklists) sn usades pels servidors de correu per filtrar el correu spam. El que fan s el segent:

Sigui la IP de qui envia el correu (el possible spammer): 1.2.3.4 Sigui la web que t la llista negra de spammers: "xbl.spamhaus.org" Llavors si al fer un DNS lookup per "4.3.2.1.xbl.spamhaus.org" dona una resposta positiva o retorna la direcci 127.0.0.2, aix significa que qui envia el correu es a la llista negra dspammers.

Es demana que feu un programa que comprovi si una direcci donada correspon a un spammer.

http://support.simpledns.com/kb/a147/dns-blacklist-dnsbl-rbl-plug-in.aspx

http://en.wikipedia.org/wiki/DNSBL

Nota: Podeu fer servir InetAddress.getByName per comprovar si s spammer o no una direcci. In Java, all integer types (even byte) are signed. When an integer is signed, one of its bits becomes the sign bit, meaning that the maximum magnitude of the number is halved.

Per exemple: el nmero 208 en binari dun byte s 1101 0000, com que comena per 1 s considerar un nmero negatiu i JAVA li dona el valor com a int de -48 (si debugueu el programa amb la IP 208.... ho podeu comprovar). Per tant haureu de sumar 256 per a que el valor sigui 208 (-48+256=208).

http://ca.wikipedia.org/wiki/Complement_a_dos -48 s el C2 de 48 en 8 bits 28-48=256-48=208

Soluci:

package spamChequeix;import java.net.*;

public class SpamChecker { public static String webDNSBL = "sbl.spamhaus.org";

public static void main(String[] args) throws UnknownHostException {if (args.length==0) {if (esSpammer("208.73.210.0")) { //208.73.210.0System.out.println(" es un spammer conegut.");} else {System.out.println(" no es un spammer conegut.");}} else {for (String argument: args) {if (esSpammer(argument)) {System.out.println(argument + " es un spammer conegut.");} else {System.out.println(argument + " no es un spammer conegut.");}}} }

private static boolean esSpammer(String arg) { try { InetAddress direccio = InetAddress.getByName(arg); byte[] vIP = direccio.getAddress(); String consulta = webDNSBL; for (byte octet : vIP) { int unsignedByte = octet < 0 ? octet + 256 : octet; // consulta = unsignedByte + "." + consulta; } InetAddress direccioRetornada = InetAddress.getByName(consulta); System.out.println("Direccio retornada: "+ direccioRetornada); return true; } catch (UnknownHostException e) { return false; } }}

3. Els fitxers de logs dun servidor Web (Apache en el nostre cas) permet veure les IP dels hosts que han accedit al lloc web. Normalment, en analitzar els logs, sobt ms informaci si enlloc de les IPs surten el noms. De fet la majoria de servidors Web poden emmagatzemar noms (fent ells mateixos una consulta DNS), per per un tema de rendiment aquesta possibilitat no la fan servir.

Es demana fer un programa que canvi les IPs per noms al fitxer de log i les mostri per pantalla.

Teniu un exemple de log a http://www.monitorware.com/en/logsamples/apache.php

Es a dir que agafi, per exemple, la lnia:

216.58.210.131 - - [07/Mar/2004] "GET /twiki/Main/Double_bounce_sender HTTP/1.1" 401 12846

I la mostri com:

www.google.es - - [07/Mar/2004] "GET /twiki/Main/Double_bounce_sender HTTP/1.1" 401 12846

Soluci:package processaLog;import java.io.*;import java.net.*;

public class LogWebProcessor {

public static void main(String[] args) { try (FileInputStream fin = new FileInputStream(args[0]); Reader in = new InputStreamReader(fin); BufferedReader bin = new BufferedReader(in);) { for (String liniaLlegida = bin.readLine();liniaLlegida != null; liniaLlegida = bin.readLine()) { int index = liniaLlegida.indexOf(' '); String ip = liniaLlegida.substring(0, index); String laResta = liniaLlegida.substring(index); try { InetAddress direccio = InetAddress.getByName(ip); System.out.println(direccio.getHostName() + laResta); } catch (UnknownHostException ex) { System.out.println("Host desconegut --> "+liniaLlegida); } } } catch (IOException ex) { System.out.println("Excepcio: " + ex); } }}

4. Com ja sabem un socket s una abstracci que permet la comunicaci entre processos sense necessitat de conixer el funcionament dels protocols de comunicaci ( tot i que aquests estiguin en sistemes diferents ).

Sabem tamb que es necessiten crear 2 sockets (un a la mquina local i un altre a la mquina remota) i que ladrea dun socket compren ladrea IP ms el nmero de port.

Tenint en compte que per crear un socket tenim els segents constructors:

1) Socket(InetAddress remoteAddr, int remotePort)2) Socket(String remoteHost, int remotePort)3) Socket(InetAddress remoteAddr, int remotePort, InetAddress localAddr, int localPort)4) Socket(String remoteHost, int remotePort, InetAddress localAddr, int localPort)5) Socket()

Per exemple:

socket = new Socket(www.google.es, 15);

Indiqueu per cada constructor quines sn les adreces IP+port de la mquina local i remota.

(1) i (2): IP local i port local agafen la IP local per defecte i qualsevol port disponible. (3) i (4): Especificar IP local i port local t sentit quan tenim un ordinador amb mltiples interfcies. (5): crea un socket no connectat. Sha de connectar explcitament amb el mtode connect().

Nota: podeu fer servir els segents mtodes per comprovar exactament els diferents valor IP+port:

InetAddress getInetAddress()int getPort()InetAddress getLocalAddress()int getLocalPort()SocketAddress getRemoteSocketAddress()SocketAddress getLocalSocketAddress()

Mireu la soluci de lexercici 5.

5. Un servidor daytime simplement envia al client la data i hora actuals com un string. Aquest servei segueix el protocol Daytime (https://tools.ietf.org/html/rfc867) i es pot implementar mitjanant TCP o UDP.

En aquest exercici, nosaltres farem servir TCP.

Encara que hi ha webs com time.nist.gov que proporcionen aquest servei, per controlar el servidor, poden configurar-lo a una mquina virtual Ubuntu. Podeu seguir la segent guia per fer-ho:

http://technoyouth10.blogspot.com.es/2012/07/how-to-enableopen-daytime-service-port.html

Es demana que feu amb Java un client Daytime TCP, es a dir, un programa que es connecti al servidor Daytime i mostri la data i hora que li envi el servidor.

Per fer-lo seguiu els segents passos:

a. Crear una instancia socket amb la direcci del servidor daytime (pot ser la IP de la mquina Ubuntu amb el servei Daytime activat) i el port 13 (s el port per on escolta el servidor Daytime):

varSocket = new Socket(servidor, port);

Nota: si la sentncia anterior retorna sense emetre una excepci, vol dir que sha creat satisfactriament la connexi TCP entre client i servidor (fase destabliment de connexi de TCP).

b. Cada socket t associat un InputStream pel qual podem rebre seqncies de bytes del servidor i un OutputStream pel qual podem enviar seqncies de bytes al servidor. Podem accedir-hi mitjanant:

InputStream in = varSocket.getInputStream();OutputStream out = varSocket.getOutputStream(); Nota: en aquest exercici noms s necessari l InputStream ja que no hem denviar dades al servidor.

Per enviar dades podem fer servir el mtode write() de lOutputStream i per rebre el mtode read() de lInputStream.

Aix, per llegir les dades del socket, podrem fer:

for (int c = in.read(); c != -1; c = in.read()) {}

Nota: Si la connexi es tanca per la part del servidor, el mtode read() retorna -1. Per tant, podem fer servir aix com a condici per finalitzar el for.

I per escriure al socket podem fer:

out.write(dades);

c. Tancar la connexi amb el mtode close()del socket.

Notes finals: Si el servidor rebutja la connexi, el socket llenar una excepci ConnectException.

Si el servidor es penja mentre esteu connectats, el socket llenar una excepci SocketTimeoutException. El temps que espera per llanar aquesta excepci es pot configurar mitjanant el mtode setSoTimeout(). Teniu en compte que un servidor molt carregar podria trigar bastant de temps a respondre, la qual cosa podria acabar en una excepci per timeout. Si voleu evitar aquests casos, establiu un temps gran amb el mtode setSoTimeout().

Els sockets TCP envien i reben seqncies de bytes. Si voleu enviar un string, el podeu convertir en bytes mitjanant el mtode getBytes() de la classe String:

byte[] dades = varString.getBytes();

Soluci:

package daytimeClient_v3;import java.net.*;import java.io.*;

public class DayTimeClient {

public static void main(String[] args) {Socket varSocket = null;try {//creem el socket tcp. Si el constructor retorna vol dir que la fase de connexio TCP//ha finalitzat amb exit-->el servidor enviara la data+hora//socket = new Socket("time.nist.gov", 13);varSocket = new Socket("192.168.1.30", 13);

//exercici 4: mostrem ip+port local/remot System.out.println("varSocket.getLocalSocketAddress() --> "+ varSocket.getLocalSocketAddress());System.out.println(" varSocket.getLocalAddress().getHostAddress() --> "+ varSocket.getLocalAddress().getHostAddress());System.out.println(" varSocket.getLocalAddress().getLocalPort() --> "+ varSocket.getLocalPort());System.out.println("varSocket.getRemoteSocketAddress() --> "+ varSocket.getRemoteSocketAddress());System.out.println(" varSocket.getInetAddress() --> "+ varSocket.getInetAddress());System.out.println(" varSocket.getPort() --> "+ varSocket.getPort());

//cada socket te associat un inputStrem pel qual llegirem amb el mtode //read el que ens envii el servidorInputStream in = varSocket.getInputStream();

//Si la connexi es tanca per la part del servidor, el mtode read() retorna -1. Per tant, //podem fer servir aix com a condici per finalitzar el for.char [] arrayDeChars= new char[255];int index=0;for (int c = in.read(); c != -1; c = in.read()) {arrayDeChars[index]=(char) c;index++;}arrayDeChars[index]='\0';

//mostrem el contingut de arrayDeCharsindex=0;while (arrayDeChars[index]!='\0') {System.out.print(arrayDeChars[index]);index++;}

//tornem a mostrar el contingut de arrayDeCharsSystem.out.println(">>"+new String(arrayDeChars));

} catch (IOException ex) {System.out.println("IOException "+ex);} finally {if (varSocket != null) {try {varSocket.close();} catch (IOException ex) {System.out.println("IOException "+ex);}}}}}