Práctica 5 | Sockets en Java



Introducción

Sockets

Un socket es un punto de comunicación por el cual un proceso puede emitir o recibir información. Los sockets son una innovación del UNIX de Berkeley. Estos permiten tratar una conexión a la red como otro flujo de bytes del que se puede leer o escribir. Históricamente los sockets son la extensión de una de las ideas más importantes de UNIX: que toda la entrada/salida debe parecerle entrada/salida de archivos al programador. Los sockets esconden del programador los detalles de bajo nivel de la red.


Un socket puede realizar siete operaciones básicas:

- Conectarse a una maquina remota.
- Enviar datos.
- Recibir datos.
- Cerrar una conexión.
- Ligarse a un puerto.
- Escuchar datos entrantes.
- Aceptar conexiones de máquinas remotas en el puerto al que se ligó.

Sockets clientes

Los sockets clientes se usan de la forma siguiente:
1.- El nuevo socket es creado usando un constructor Socket().
2.- El socket intenta conectarse a un host remoto.
3.- Una vez que la conexión es establecida los hosts local y remoto obtienen flujos de
entrada y salida para el socket y usan esos flujos para enviarse datos uno a otro. Esta
conexión es full-duplex, ambos hosts pueden enviar y recibir datos simultáneamente. Lo
que significan los datos depende del protocolo. Normalmente se pondrían de acuerdo sobre
algún handshaking antes de transmitir datos de uno a otro.
4.- Cuando la transmisión de datos esta completa, uno o ambos cierra la conexión.

Con lo anterior se pretende en esta práctica aplicar todos los conocimientos sobre sockets cliente para lograr establecer una conexión y enviar objetos entre máquinas.

Objetivos:

1: Mover objetos de una maquina a otra usando un servidor como intermediario.
2: Mejorar los programas que se empleen en esta practica
3: Desarrollar programas funcionales

Desarrollo.

Tomé el código del sistema solar e hice ciertas modificaciones, primero reduje el número de planetas para facilitar un poco el desarrollo, extendí la clase MouseAdapter e implemente LeeRed, además se agregaron nuevas variables y clases para poder conectar todo. En el apartado 3d casi todo quedo igual.

Posteriormente se crear el método de los eventos del mouse(general), el método de envía el cual le pasa los valores a la clase Red verificando si se ordenó con un mouse evento o un actionstring, el método Cambiar vista mouse el cual cambia la traslación, rotación y los planetas de acuerdo a lo que le indiquemos en ese cliente al hacer clic en los planetas.



luego se desarrolló la clase anidada combohandler(combobox) la cual reacciona cuando sucede un cambio en el cliente, gracias al actionstring y de igual forma cambia la rotación, traslación y los planetas que se seleccionaron.


Después se creó el método leered en donde se envían los paquetes de información atreves de la Red donde todos los clientes percibirán el cambio.
Finalmente se llamó en el main a solarsis.

Cabe señalar que ocupe las clases que se nos proporcionaron para la creación del socket, Red de conexión, del servidor del chat y las clases adicionales para hacer funcionar esta mejora al sistema solar en java 3d en las cuales no modifique prácticamente nada.




Resultado


Códigos

Solarsis

import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.picking.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.net.*;
//sudo cp /usr/lib/jni/libj3dcore-ogl.so /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext
//sudo cp /usr/share/java/vecmath-*.jar /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/ext

public class SolarSis extends MouseAdapter implements LeeRed{

    protected Transform3D viewTransform = new Transform3D();
    protected Vector3f viewVector;
    protected ViewingPlatform vp = null;
    protected TransformGroup viewTG = null;
    private TransformGroup riderPos;
    private TransformGroup earthRotX;
    private TransformGroup solRotX;
    private TransformGroup earthTransX;
    private TransformGroup marteRotX;
    private TransformGroup marteTransX;
    SimpleUniverse universe;
    private PickCanvas pickCanvas;
    private JComboBox jcb;
    private JTextArea jta;
    private MiniBrowser miniB;
    String opcs[] = {"Sol", "Tierra", "Marte"};
    
    Red red;
    ComboHandler combo;

    public SolarSis() {
        red = new Red(this);
        
        
        BranchGroup group = new BranchGroup();
        Appearance appsol = new Appearance();
        Appearance appearth = new Appearance();
        Appearance appLun = new Appearance();
        Appearance appmart = new Appearance();
        TextureLoader tex = new TextureLoader(getClass().getResource("TIERRA.JPG"), null);
        appearth.setTexture(tex.getTexture());
        tex = new TextureLoader(getClass().getResource("MARTE.JPG"), null);
        appmart.setTexture(tex.getTexture());
        tex = new TextureLoader(getClass().getResource("SOL.JPG"), null);
        appsol.setTexture(tex.getTexture());
        tex = new TextureLoader(getClass().getResource("LUNA.JPG"), null);
        appLun.setTexture(tex.getTexture());
        Sphere earth = new Sphere(0.045f, Primitive.GENERATE_NORMALS
                | Primitive.GENERATE_TEXTURE_COORDS, 32, appearth);
        earth.setUserData("Tierra");
        Sphere luna = new Sphere(0.018f, Primitive.GENERATE_NORMALS
                | Primitive.GENERATE_TEXTURE_COORDS, 32, appLun);
        luna.setUserData("Luna");
        Sphere marte = new Sphere(0.049f, Primitive.GENERATE_NORMALS
                | Primitive.GENERATE_TEXTURE_COORDS, 32, appmart);
        marte.setUserData("Marte");
        Sphere sol = new Sphere(0.33f, Primitive.GENERATE_NORMALS
                | Primitive.GENERATE_TEXTURE_COORDS, 32, appsol);
        sol.setUserData("Sol");
        
        earthRotX = Posi.rotate(earth, new Alpha(-1, 1250));
        solRotX = Posi.rotate(sol, new Alpha(-1, 1250));
        earthTransX = Posi.translate(earthRotX, new Vector3f(0.0f, 0.0f, 0.7f));
        TransformGroup earthRotGroupX = Posi.rotate(earthTransX, new Alpha(-1, 5000));
        group.addChild(earthRotGroupX);

        TransformGroup lunaRotX = Posi.rotate(luna, new Alpha(-1, 1249));
        TransformGroup lunaTransX = Posi.translate(lunaRotX, new Vector3f(0.0f, 0.0f, 0.1f));
        TransformGroup lunaRotGroupX = Posi.rotate(lunaTransX, new Alpha(-1, 2000));
        earthTransX.addChild(lunaRotGroupX);
        
        marteRotX = Posi.rotate(marte, new Alpha(-1, 12820));
        marteTransX = Posi.translate(marteRotX, new Vector3f(0.0f, 0.0f, 0.52f));
        TransformGroup marteRotGroupX = Posi.rotate(marteTransX, new Alpha(-1, 6000));
        group.addChild(marteRotGroupX);
        
        group.addChild(solRotX);
        GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas = new Canvas3D(config);
        canvas.setSize(400, 400);
        universe = new SimpleUniverse(canvas);
        universe.getViewingPlatform().setNominalViewingTransform();

        solRotX.setCapability(Group.ALLOW_LOCAL_TO_VWORLD_READ);
        solRotX.setCapability(Group.ALLOW_CHILDREN_EXTEND);
        solRotX.setCapability(Group.ALLOW_CHILDREN_WRITE);
        solRotX.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

        earthRotX.setCapability(Group.ALLOW_LOCAL_TO_VWORLD_READ);
        earthRotX.setCapability(Group.ALLOW_CHILDREN_EXTEND);
        earthRotX.setCapability(Group.ALLOW_CHILDREN_WRITE);
        earthRotX.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        
        marteRotX.setCapability(Group.ALLOW_LOCAL_TO_VWORLD_READ);
        marteRotX.setCapability(Group.ALLOW_CHILDREN_EXTEND);
        marteRotX.setCapability(Group.ALLOW_CHILDREN_WRITE);
        marteRotX.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

        vp = universe.getViewingPlatform();
        viewTG = vp.getViewPlatformTransform();
        universe.addBranchGraph(group);
        JFrame f = new JFrame("Sistema Solar");
        JPanel jp = new JPanel();
        f.setLayout(new BorderLayout());
        miniB = new MiniBrowser();
        combo = new ComboHandler();
        jp.add(new ComboPanel(opcs, combo));
        jp.add(miniB);
        JScrollPane dst_pane = new JScrollPane(jp);
        JSplitPane split_pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, canvas, dst_pane);
        split_pane.setResizeWeight(0.5);
        split_pane.setContinuousLayout(true);
        f.add("Center", split_pane);
        pickCanvas = new PickCanvas(canvas, group);
        pickCanvas.setMode(PickCanvas.BOUNDS);
        canvas.addMouseListener(this);
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }

    public void mouseClicked(MouseEvent e) {//metodo de eventos mouse
        envia(e);
        cambiarVistaMouse(e);
    }
    
    public void cambiarVistaMouse(MouseEvent e){
        pickCanvas.setShapeLocation(e);
        PickResult result = pickCanvas.pickClosest();
        if (result == null) {
            System.out.println("nada recibido");
        } else {
            Primitive p = (Primitive) result.getNode(PickResult.PRIMITIVE);
            Shape3D s = (Shape3D) result.getNode(PickResult.SHAPE3D);
            if (p != null) {
                System.out.println("UserData1: " + p.getUserData());
                System.out.println(p.getClass().getName());
                viewVector = new Vector3f(.0f, .0f, 0.95f);
                viewTransform.setTranslation(viewVector);
                viewTG.setTransform(viewTransform);
                vp.detach();
                if (p.getUserData().equals("Sol")) {
                    solRotX.addChild(vp);
                }
                if (p.getUserData().equals("Tierra")) {
                    earthRotX.addChild(vp);
                }
                if (p.getUserData().equals("Marte")) {
                    marteRotX.addChild(vp);
                }
                miniB.showPage("http://localhost:8080/" + p.getUserData() + ".html", true);
            } else if (s != null) {
                System.out.println("UserData2: " + s.getUserData());
                System.out.println(s.getClass().getName());
                jta.setText(s.getClass().getName());
            } else {
                System.out.println("null");
            }
        }
    }

    class ComboHandler implements AccionString {//clase anidada

        public void accion(String nombre) {
            envia(nombre);
            cambiarVistaCombo(nombre);
        }

        public void cambiarVistaCombo(String nombre){
            viewVector = new Vector3f(.0f, .0f, 0.95f);
            viewTransform.setTranslation(viewVector);
            viewTG.setTransform(viewTransform);
            vp.detach();
            if (nombre.equals("Sol")) {
                solRotX.addChild(vp);
            }
            if (nombre.equals("Tierra")) {
                earthRotX.addChild(vp);
            }
            if (nombre.equals("Marte")) {
                marteRotX.addChild(vp);
            }
            miniB.showPage("http://localhost:8080/" + nombre + ".html", true);
        }
    }
    
    public void envia(Object obj){
        if(obj instanceof String){
            String planeta = (String)obj;
            red.escribeRed(planeta);
        }
        if(obj instanceof MouseEvent){
            MouseEvent planetaEvent = (MouseEvent)obj;
            red.escribeRed(planetaEvent);
        }
    }
    
    public void leeRed(Object obj){
        System.out.println("clase obtenida"+  obj.getClass().getName());
        if(obj instanceof String){
            String planeta = (String)obj;
            combo.cambiarVistaCombo(planeta);
        }
        if(obj instanceof MouseEvent){
            MouseEvent planetaEvent = (MouseEvent)obj;
            cambiarVistaMouse(planetaEvent);
        }
    }
public static void main(String a[]) {
new SolarSis();
}
}

jhttp

import java.net.*;
import java.io.*;
import java.util.*;

//java jhttp . 5050

public class jhttp extends Thread {

  Socket theConnection;
  static File docroot;
  static String indexfile = "index.html";
  
  public jhttp(Socket s) {
    theConnection = s;
  }

  public static void main(String[] args) {

    int thePort;
    ServerSocket ss;

    // get the Document root
    try {
      docroot = new File(args[0]);
    }
    catch (Exception e) {
      docroot = new File(".");
    }
    
    // set the port to listen on
    try {
      thePort = Integer.parseInt(args[1]);
      if (thePort < 0 || thePort > 65535) thePort = 80;
    }  
    catch (Exception e) {
      thePort = 8080;
    }  
                
    try {
      ss = new ServerSocket(thePort);
      System.out.println("Accepting connections on port " 
        + ss.getLocalPort());
      System.out.println("Document Root:" + docroot);
      while (true) {
        jhttp j = new jhttp(ss.accept());
        j.start();
      }
    }
    catch (IOException e) {
      System.err.println("Server aborted prematurely: "+e);
    }
  
  }

  public void run() {
  
    String method;
    String ct;
    String version = "";
    File theFile;
  
    try {
      PrintStream os = new PrintStream(theConnection.getOutputStream());
      DataInputStream is = new DataInputStream(theConnection.getInputStream());
      String get = is.readLine();
      System.out.println("recibi "+get);
      StringTokenizer st = new StringTokenizer(get);
      method = st.nextToken();
      if (method.equals("GET")) {
        String file = st.nextToken();
        if (file.endsWith("/")) file += indexfile;
        ct = guessContentTypeFromName(file);
        if (st.hasMoreTokens()) {
          version = st.nextToken();
        }
        // loop through the rest of the input lines 
        
        while ((get = is.readLine()) != null) {
          if (get.trim().equals("")) break;        
        }

        try {
          theFile = new File(docroot, file.substring(1,file.length()));
          FileInputStream fis = new FileInputStream(theFile);
          byte[] theData = new byte[(int) theFile.length()];
          // need to check the number of bytes read here
          fis.read(theData);
          fis.close();

          if (version.startsWith("HTTP/")) {  // send a MIME header
            //os.print("HTTP("+new Date()+")\r\n");
            os.println("HTTP/1.1 200 OK");
            Date now = new Date();
            os.print("Date: " + now + "\r\n");
            os.print("Server: jhttp 1.0\r\n");
            os.print("Content-length: " + theData.length + "\r\n");
            os.print("Content-type: " + ct + "\r\n\r\n");
          }  // end try
          
          // send the file
          os.write(theData);
          System.out.println("envio "+theData);
          os.close();
        }  // end try
        catch (IOException e) {  // can't find the file
          if (version.startsWith("HTTP/")) {  // send a MIME header
            os.print("HTTP/1.0 404 File Not Found\r\n");
            Date now = new Date();
            os.print("Date: " + now + "\r\n");
            os.print("Server: jhttp 1.0\r\n");
            os.print("Content-type: text/html" + "\r\n\r\n");
          } 
          os.println("<HTML><HEAD><TITLE>File Not Found</TITLE></HEAD>");
          os.println("<BODY><H1>HTTP Error 404: Archivo Not Found</H1></BODY></HTML>");
          os.close();
        }
      }
      else {  // method does not equal "GET"
        if (version.startsWith("HTTP/")) {  // send a MIME header
          os.print("HTTP/1.0 501 Not Implemented\r\n");
          Date now = new Date();
          os.print("Date: " + now + "\r\n");
          os.print("Server: jhttp 1.0\r\n");
          os.print("Content-type: text/html" + "\r\n\r\n"); 
        }       
        os.println("<HTML><HEAD><TITLE>Not Implemented</TITLE></HEAD>");
        os.println("<BODY><H1>HTTP Error 501: Not Implemented</H1></BODY></HTML>");
        os.close();
      }
    }
    catch (IOException e) {
    
    }
    try {
      theConnection.close();
    }
    catch (IOException e) {
    }

  }
  
  public String guessContentTypeFromName(String name) {
    if (name.endsWith(".html") || name.endsWith(".htm")) return "text/html";
    else if (name.endsWith(".txt") || name.endsWith(".java")) return "text/plain";
    else if (name.endsWith(".gif") ) return "image/gif";
    else if (name.endsWith(".class") ) return "application/octet-stream";
    else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) return "image/jpeg";
    else return "text/plain";
  }

}

verysimplechatserver

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;

public class VerySimpleChatServer {
    ArrayList clientObjectOutputStreams;
    public class ClientHandler implements Runnable {
        public void run(){
            try {
                while(true) {
                    Object obj = reader.readObject();
                    tellEveryone(obj, writer);
                }
            }
            catch(Exception exception) {
                exception.printStackTrace();
            }
        }

        ObjectOutputStream writer;
        ObjectInputStream reader;
        Socket sock;

        public ClientHandler(Socket socket, ObjectOutputStream objectoutputstream){
            try {
                writer = objectoutputstream;
                sock = socket;
                reader = new ObjectInputStream(sock.getInputStream());
            } catch(Exception exception) {
                System.out.println((new StringBuilder()).append("Exce Servidor reader ").append(exception).toString());
                exception.printStackTrace();
            }
        }
    }
    public VerySimpleChatServer(){}
    public 
            
            static void main(String args[]){
        (new VerySimpleChatServer()).go();
    }
    public void go(){
        clientObjectOutputStreams = new ArrayList();
        try {
            ServerSocket serversocket = new ServerSocket(5000);
            do {
                Socket socket = serversocket.accept();
                ObjectOutputStream objectoutputstream = new ObjectOutputStream(socket.getOutputStream());
                clientObjectOutputStreams.add(objectoutputstream);
                Thread thread = new Thread(new ClientHandler(socket, objectoutputstream));
                thread.start();
                System.out.println("got a conexion");
            } while(true);
        }
        catch(Exception exception){
            exception.printStackTrace();
        }
    }
    public void tellEveryone(Object obj, ObjectOutputStream objectoutputstream){
        Iterator iterator = clientObjectOutputStreams.iterator();
        do {
            if(!iterator.hasNext())
                break;
            try {
                ObjectOutputStream objectoutputstream1 = (ObjectOutputStream)iterator.next();
                if(!objectoutputstream1.equals(objectoutputstream)){
                    objectoutputstream1.writeObject(obj);
                    objectoutputstream1.flush();
                }
            } catch(Exception exception) {
                exception.printStackTrace();
            }
        } while(true);
    }
}

Combopanel

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class ComboPanel extends JPanel implements ActionListener {
 JComboBox jcb;
 AccionString as; 
 public ComboPanel(String opcs[], AccionString as){
    this.as = as;
    Vector combo=new Vector();
    for(int i = 0; i < opcs.length; i++){
    combo.addElement(opcs[i]); 
    }
    jcb=new JComboBox(combo);
    jcb.addActionListener(this);
    add(jcb);  
 }
 public void actionPerformed(ActionEvent e){
    int aux;
    Object botones= e.getSource();
    if(botones instanceof JComboBox){
JComboBox jcb= (JComboBox) e.getSource();
String nombre=(String)jcb.getSelectedItem();
System.out.println("Se eligio ("+nombre +")");
                as.accion(nombre);
    }
 }
}

Actionstring

public interface AccionString {
public void accion(String s);
}

leered

public interface LeeRed {
void leeRed(Object obj);
}

paletagral

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

class PaletaGral extends JPanel implements ActionListener {
JButton botones[];
int sel=-1;
        AccionInt actor;
PaletaGral(Object arr[],LayoutManager lm, AccionInt ai){             
//if(arr instanceof ImageIcon[]
actor=ai;
                setLayout(lm);
botones=new JButton[arr.length];
for(int i=0; i< botones.length;i++){
if(arr[i] instanceof ImageIcon)
botones[i]=new JButton((ImageIcon)arr[i]);
if(arr[i] instanceof String)
botones[i]=new JButton((String)arr[i]);
add(botones[i]);
botones[i].addActionListener(this);
}
setVisible(true);
}
        public int getSeleccion(){
return sel;
}
public void actionPerformed(ActionEvent e){
JButton b=(JButton)e.getSource();
for(int i=0; i< botones.length;i++){
if(b == botones[i]){
sel=i;
}
}
actor.accion(sel);
}
}

Video



Comentarios

Entradas populares