Programarea în reţea – Datagrame şi Url-uri

 

Programarea în reţea – Datagrame şi Url-uri 1

1. Scopul lucrării 1

2. Noţiuni preliminiare. 1

3. Server de timp (UDP) 2

4. Lucrul cu URL-uri 3

5. Citirea şi scrierea către un URL.. 4

6. Browser java. 6

 

1. Scopul lucrării

Scopul acestei lucrări este de insuşire a următoarelor mecanisme;

- comunicarea prin UDP

            - lucrul cu URL-uri

            - comunicarea cu un CGI

2. Noţiuni preliminiare

 

Clienţii care comunică prin intermediul TCP, utilizând socket-uri, au un canal dedicat, iar transmisia datelor este sigură. Datele sunt recepţionate în ordinea în care acestea au fost trimise.

 

In contrast, când datele sunt transmise prin UDP, ajungerea acestora la destinaţie nu este garantată, de asemenea, ordinea de sosire la destinaţie a datagramelor poate să difere de ordinea în care acestea au fost transmise.

 

Avantajul lucrului cu datagrame este creşterea vitezei cu care pachetele (datagramele) ajung la destinaţie. Există cazuri în care viteza de transmisie a datelor este mai importantă decât garantarea 100% a ajungerii acestora la destinaţie. De exemplu în cazul transmiterii unui semnal audio în timp real, viteza de transmitere a acestuia este mai importantă decât garantarea ajungerii la destinaţie.

 

In java pentru implementarea protocolului UDP sunt utilizate clasele: DatagramPacket şi DatagramSocket. Spre deosebire de programarea TCP, în cazul UDP nu există conceptul de ServerSocket. Atât serverul cât şi clientul utilizează DatagramSocket pentru realizarea conexiunii. Pentru transmiterea şi recepţionarea datelor se utilizează clasa DatagramPacket.

             

Programarea prin url-uri se desfăşoară la un nivel mai înalt decât programarea prin socketuri. Utilizând clasa URL, se va putea deschide o conexiune către o resursa aflată pe web. O data deschisă conexiunea, către resursă, clientul va putea citi date sau trimite date către respectiva resursă.

 

URL este acronimul de la Uniform Resource Locator (de asemenea este şi numele unei clase java). Un URL este un pointer către o resursă din Internet.

 

Sintaxa generală a unui URL este:

            protocol://hostname[:port]/path/filename#ref

 

3. Server de timp (UDP)

 

In cadrul acestei secţiuni este construit un server de timp care va trimite la cerere data curentă către clienţii care solicită acest lucru. De asemenea este construit şi clientul care accesează serviciile serverului de timp.

 

La nivelul serverului se creează un obiect DatagramSocket, care va primi ca parametru portul pe care serverul va începe ascultarea.

 

            DatagramSocket socket = new DatagramSocket(1977);

 

In continuare se construieşte un obiect DatagramPacket, care va fi utilizat de către server pentru a recepţiona cererea de la client. O dată construit obiectul DatagramPacket, serverul va începe ascultarea portului 1977, prin invocarea metodei receive().

 

            byte[] buf = new byte[256];

            DatagramPacket packet = new DatagramPacket(buf,buf.length);

            socket.receive(packet);

 

In momentul în care un client doreşte să apeleze la serviciile serverului, acesta va trimite un pachet către server. Serverul citeşte din cadrul pachetului portul şi adresa clientului, şi îi va trimite acestuia un pachet ce conţine data curentă.

 

            InetAddress address = packet.getAddress();

            int port = packet.getPort();

             buf = ((new Date()).toString()).getBytes();

 packet = new DatagramPacket(buf,buf.length,address,port);

 socket.send(packet);

           

Un client, pentru a se conecta la server, trebuie să creeze un obiect DatagramSocket, şi să trimită un pachet către server. Spre deosebire de server, clientul nu este obligat să specifice nici un port în momentul creierii obiectului DatagramSocket, întrucât se atribuie automat un port liber respectivului obiect.

 

import java.io.*;

import java.net.*;

import java.util.*;

 

public class TimeServer extends Thread{

 

  boolean running=true;

  public TimeServer() {start();}

 

  public void run(){

  try{

    DatagramSocket socket = new DatagramSocket(1977);

    while(running){

      //asteapta client

      byte[] buf = new byte[256];

      DatagramPacket packet = new DatagramPacket(buf,buf.length);

      socket.receive(packet);

      //citeste adresa si portul clientului

      InetAddress address = packet.getAddress();

      int port = packet.getPort();

      //trimite un reply catre client

      buf = ((new Date()).toString()).getBytes();

      packet = new DatagramPacket(buf,buf.length,address,port);

      socket.send(packet);

   }

    }catch(Exception ex){ex.printStackTrace();}

  }

  public static void main(String[] args) {

    TimeServer timeServer1 = new TimeServer();

  }

}

 

 import java.io.*;

 import java.net.*;

 import java.util.*;

 

public class Client {

 

  public static void main(String[] args) {

  try{

    DatagramSocket socket = new DatagramSocket();

    byte[] buf = new byte[256];

 

    DatagramPacket packet = new DatagramPacket(buf,buf.length,

      InetAddress.getByName("localhost"),1977);

    socket.send(packet);

    packet = new DatagramPacket(buf,buf.length);

    socket.receive(packet);

 

    System.out.println(new String(packet.getData()));

  }catch(Exception ex){ex.printStackTrace();}

  }

}

 

4. Lucrul cu URL-uri

 

In această secţiune este prezentat modul de lucru în java cu URL-uri.

URL este acronimul pentru Uniform Resource Locator si reprezinta o referinta (adresa) la o resursa aflata pe Internet. Aceasta este în general un fisier reprezentând o pagina Web sau o imagine, însa un URL poat referi si interogari la baze de date, rezultate ale unor comenzi (programe), etc.

 

Pentru a accesa o resursă din Internet identificată printr-un URL, în java, primul pas este de a crea un obiect URL.

 

            URL utcn = new URL(“www.utcluj.ro”);

 

Clasa URL conţine metode prin intermediul cărora se pot afla toate componentele unui URL: getProtocol(), getPort(), getHost(), getFile(), getRef().

 

Odată creat obiectul URL, se utilizează metoda openStream() pentru a deschide un flux de intrare, prin intermediul căruia se citeşte conţinutul respectivului URL.

               BufferedReader in = new BufferedReader(
                                                             new InputStreamReader(
                                                             utcn.openStream()));
               String inputLine;
               while ((inputLine = in.readLine()) != null)
                   System.out.println(inputLine);
               in.close();
 

5. Citirea şi scrierea către un URL

               
Daca se doreşte să se realizeze mai mult decât citirea conţinutului unui URL, atunci din cadrul clasei URL se poate apela metoda openConnection(). Această metodă va returna un obiect URLConnection. Acest obiect va putea fi utilizat pentru operaţii de scriere, citire precum şi interogări către un URL. 

           

URLConnection connection = utcn.openConnection();

           

In continuare este prezentat un scurt program care citeşte conţinutul unui URL utilizând clasa URLConnection.     

           

import java.net.*;
import java.io.*;
 
public class URLConnectionReader {
    public static void main(String[] args) throws Exception {
        URL utcluj = new URL(http://www.utcluj.ro);
        URLConnection con = yahoo.openConnection();
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                con.getInputStream()));
        String inputLine;
 
        while ((inputLine = in.readLine()) != null) 
            System.out.println(inputLine);
        in.close();
    }
}

 

Multe pagini HTML conţin form-uri (zone de text, butoane etc.) care permit introducerea de date şi transmiterea acestora către server. După completarea câmpurilor se apasă un buton iar browserul web va transmite datele către URL-ul corespunzător. URL-ul care recepţionează datele este un script cgi-bin. Acesta procesează datele şi transmite către client un răspuns, care de obicei este o altă pagină HTML.

 

Programele java pot interacţiona cu script-urile cgi-bin. Ele trebuie să fie capabile să scrie date către un URL. Acest lucru se realizează utilizând clasa URLConnection.

 

In listingul următor este exemplificat modul în care un program java poate interacţiona cu un script cgi-bin.

 

try{      

       String data=””;                   

        data += URLEncoder.encode("nume") + "=" + URLEncoder.encode("Adi”);

        data += "&" + URLEncoder.encode("nota”) + "=" + URLEncoder.encode("8.50”);

 

        URL url = new URL(“http://193.226.6.117:80/test/test.php");

        URLConnection conn = url.openConnection();

        conn.setDoOutput(true);

        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());

        wr.write(data);

        wr.flush();

 

        // Get the response

        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        String line;

        while ((line = rd.readLine()) != null) {

            System.out.println(line);

         }

 

        rd.close();

        wr.close();

}catch(Exception ex){ex.printStackTrace();}

 

In listingul anterior se presupune că există un script cgi-bin test.php, către care programul java trimite două variabile : nume=adi şi nota=8.50 . Scriptul cgi va citi respectivele variabile şi va transmite către programul java un răspuns. Pentru testarea listingului anterior se va reveni în cadrul laboratorului care prezintă servleturile.

                       

In listingul următor este prezentat un exemplu complet al unui applet care citeşte conţinutul unui fişier identificat printr-un URL. In cazul de faţă appletul citeşte chiar fişierul .class propriu.

 

import java.applet.*;

import java.awt.*;

import java.net.*;

import java.io.*;

 

public class FileURL extends Applet

{

     byte[] appletCode; //stocare fisier citit

 

     public void init()

     {

          try {

 

// Ceraza obiect URL

               URL url = new URL(getCodeBase(),

                    getClass().getName()+".class");

 

// Deschide conexiunea catre URL

               URLConnection urlConn = url.openConnection();

 

// Utilizeaza ByteArrayOutputStream ca un container temporar.

// Dupa terminare citire va fi convertit catre un array

               ByteArrayOutputStream tempBuffer;

 

               tempBuffer = new ByteArrayOutputStream();

 

// Creaza fluxul de citire catre URL       

               InputStream instream = urlConn.getInputStream();

 

// Citeste continutul URL-ului in bufferul temporar

               int ch;

               while ((ch = instream.read()) >= 0) {

                    tempBuffer.write(ch);

               }

 

// Converteste bufferul temporar intr-un array

               appletCode = tempBuffer.toByteArray();

          } catch (Exception e) {

               e.printStackTrace();

          }

     }

 

     public void paint(Graphics g)

     {

          g.setColor(Color.black);

 

          if (appletCode == null) {

               g.drawString("Nu s-a citit fisierul .class",

                    10, 30);

          } else {

               g.drawString("Lungimea fisierului class. "+

                    appletCode.length+" bytes .", 10, 30);

          }

     }

}

 

6. Browser java

 

In această secţiune este prezentat modul în care se poate construi în java un browser de internet.

 

 

import javax.swing.*;

import java.awt.*;

import javax.accessibility.*;

import javax.swing.event.*;

import javax.swing.text.*;

import java.net.*;

import java.io.*;

import java.awt.event.*;

 

 

public class Browser extends JPanel {

  Browser() {

    setLayout (new BorderLayout (5, 5));

    final JEditorPane jt = new JEditorPane();

    final JTextField input =

      new JTextField("http://127.0.0.1:8080");

    // read-only

    jt.setEditable(false);

    // follow links

    jt.addHyperlinkListener(new HyperlinkListener () {

      public void hyperlinkUpdate(

          final HyperlinkEvent e) {

        if (e.getEventType() ==

            HyperlinkEvent.EventType.ACTIVATED) {

          SwingUtilities.invokeLater(new Runnable() {

            public void run() {

              // Save original

              Document doc = jt.getDocument();

              try {

                URL url = e.getURL();

                jt.setPage(url);

                input.setText (url.toString());

              } catch (IOException io) {

                JOptionPane.showMessageDialog (

                  Browser.this, "Can't follow link",

                  "Invalid Input",

                   JOptionPane.ERROR_MESSAGE);

                jt.setDocument (doc);

              }

            }

          });

        }

      }

    });

    JScrollPane pane = new JScrollPane();

    pane.setBorder (

      BorderFactory.createLoweredBevelBorder());

    pane.getViewport().add(jt);

    add(pane, BorderLayout.CENTER);

 

    input.addActionListener (new ActionListener() {

      public void actionPerformed (ActionEvent e) {

        try {

          jt.setPage (input.getText());

        } catch (IOException ex) {

          JOptionPane.showMessageDialog (

            Browser.this, "Invalid URL",

            "Invalid Input",

            JOptionPane.ERROR_MESSAGE);

        }

      }

    });

    add (input, BorderLayout.SOUTH);

  }

}

 

import javax.swing.*;

 

public class Start extends JFrame{

public Start(){

                        Browser b = new Browser();

                        getContentPane().add(b);

                        pack();

                        setVisible(true);

                        }

 

public static void main(String args[])

            {

            Start s = new Start();

            }

}