Tarea1 – APLICACIÓN CLIENTE-SERVIDOR TCP/IP


Seguridad Informática

Prof. Arturo García Hernández

Departamento de Computación

26/01/2010

Nombre del Equipo: Code Busters

Nombre Matrícula
David Antonio Jiménez Xolalpa A00994415
Jonatan Elías Luna Rodríguez A01101876
Maykel Farha Boulos A01210984
Alejandro Méndez González A01210989

Funcionalidad:

  • Un diccionario, en la base de datos se encuentran las palabras, el cliente las puede consultar, modificar, dar de alto y eliminar registros, a traves del servidor.

Protocolo:

  • TCP – IP, utilizando sockets y los clientes tcp – ip  que se encuentran en el framework, por ejemplo el ServerSocket por parte de java  y TcpClient por parte de C#.

Servidor:

  • Lenguaje: Java
  • Plataforma: Ubuntu (Linux)
  • Base de datos: MySQL(externa)
  • Código:
  • import java.net.*;
    import java.io.*;
    import java.util.*;
    import java.sql.*;
    
    /**
     * Esta clase representa un servidor capaz de atender varias peticiones al mismo tiempo.
     * El servidor recibe peticiones de altas, bajas, consultas y cambios de un diccionario, el cual
     * se encuentra en una base de datos MySQL en un equipo remoto.
     * Estas peticiones las atiende creando hilos demonio para cada socket.
     * El algoritmo utilizado para atender las peticiones es el siguiente:
     * 1. Se abre un ServerSocket en el puerto 1800
     * 2. Se invoca el método accept() del ServerSocket para esperar una petición por parte de un cliente
     * 3. Al momento de recibir una petición, se guarda el Socket en un Thread, el cual se establece como un hilo demonio.
     * 4. El método run() del hilo es quien se encarga de mostrar el menú de opciones de acceso al diccionario
     * @author CodeBusters
     */
    public class NBServer
    {
    	// Se utiliza para escribir en el archivo del log del servidor
    	public static PrintWriter out;
    
    	//string de la conexión
    	public static String conexionBase = "";
    
    	// Se ejecuta el algoritmo principal del servidor
    	public static void main(String args[]) throws IOException
    	{
    		ServerSocket ss = null;
    		try
    		{
    			 // se lee la ip donde se encuentra la base datos y el archivo se llama ipsql.txt
    			 File miArchivo = new File("ipsql.txt");
    			 FileReader fileReader = new FileReader(miArchivo);
    			 BufferedReader reader = new BufferedReader(fileReader);
    			 conexionBase = reader.readLine();
    			 reader.close();
    
    			// se crea el socket del servidor con el puerto al cual se deden conectar los clientes
    			ss=new ServerSocket(1800);
    			Socket s;
    
    			//la lista de conexiones abiertas, es decir lo clientes conectados
    			ArrayList
     listaCon = new ArrayList
    ();
    
    			//se crea el archivo bitacora del servidor y se escribe la fecha
    			File f = new File("NBServerLog-" +(new java.util.Date()).getTime() + ".txt");
    			out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
    			out.println("STARTUP - " + (new java.util.Date()).toString());
    			out.flush();
    
    			// en este ciclo esta buscando la conexiones constantemente
    			while((s=ss.accept())!=null) {
    			    // se crea el nuevo hilo de la conexión
    				Thread peticionActual = new Thread(new Peticion(s));
    				String lw = "[" + (new java.util.Date()).toString() + "] IP Address: " + s.getInetAddress().toString() + ":" + s.getPort() + " - Connected";
    				System.out.println (lw);
    				out.println (lw);
    				peticionActual.setDaemon(true);
    				//se agrega a la lista de conexiones
    				listaCon.add(peticionActual);
    				//corre el hilo
    				peticionActual.start();
    				out.flush();
    			}
    
    		}catch(Exception e){
    			e.printStackTrace();
    			ss.close();
    			out.close();
    		}finally{
    			ss.close();
    			out.close();
    		}
    	}
    }
    
    /**
     * Esta clase representa una petición por parte de un cliente.
     * La Peticion se envia como método a ejecutar al Thread, para esto implementa la interfaz Runnable
     * @author CodeBusters
     */
    class Peticion implements Runnable{
    	private Socket miSocket;
    	private PrintWriter writer;
    	private BufferedReader reader;
    	private Statement estSQL = null;
    
    	public Peticion (Socket from) {
    		miSocket = from;
    		try {
    		    // se obtiene el lector y para escribir del socket
    			writer = new PrintWriter(new OutputStreamWriter(miSocket.getOutputStream()));
    			reader = new BufferedReader(new InputStreamReader(miSocket.getInputStream()));
    		}
    		catch (Throwable e) {
    			e.printStackTrace();
    		}
    	}
        // metodo run del hilo que se ejecuta cuando corre este
    	public void run() {
    		try {
    			int opcion = 0;
    			do
    			{
    			    // se imprime el menu del cliente
    				writer.println("- Menu Diccionario -\n1)Consultar definicion\n2)Agregar entrada\n3)Editar entrada\n4)Borrar entrada\n5)Salir\nEscoge una opcion");
    				writer.flush();
    
    				//se  lee la opción seleccionada
    				opcion = Integer.parseInt(reader.readLine());
    
    				// se llama el metodo correspondiente a la opcion
    				switch (opcion){
    					case 1:
    						consultarDefinicion();
    						break;
    					case 2:
    						agregarEntrada();
    						break;
    					case 3:
    						editarEntrada();
    						break;
    					case 4:
    						eliminarEntrada();
    						break;
    					case 5:
    						writer.println("Gracias por utilizar el diccionario");
    						String cadena = "[" + (new java.util.Date()).toString() + "] IP Address: " + miSocket.getInetAddress().toString() + ":" + miSocket.getPort() + " - Offline";
    						System.out.println (cadena);
    						NBServer.out.println (cadena);
    						NBServer.out.flush();
    						break;
    					default:
    						writer.println("Esa opcion no esta permitida");
    						break;
    				}
    
    			} while (opcion!=5);
    
    		}
    		catch (Throwable e) {
    			e.printStackTrace();
    		}
    
    	}
    
    	//metodo para hacer consultas a la base de datos
    	public void consultarDefinicion() {
    		try{
    			// si no esta la conexion  a la base de datos se crea
    			if(estSQL==null){
    				Class.forName("com.mysql.jdbc.Driver").newInstance();
    				Connection conex = DriverManager.getConnection(NBServer.conexionBase, "root", "root");
    				estSQL = conex.createStatement();
    			}
    
    			//se pide la palabra
    			writer.println("Que palabra deseas consultar?");
    			writer.flush();
    			String palabra = reader.readLine();
    
    			//se hace la consulta en la base de datos
    			ResultSet rs1 = estSQL.executeQuery("SELECT palabra, definicion FROM entradas WHERE palabra='"+palabra+"'");
    
    			// bitacora
    			String lw = "[" + (new java.util.Date()).toString() + "] IP Address: " + miSocket.getInetAddress().toString() + ":" + miSocket.getPort() + " - SELECT " + palabra;
    			System.out.println (lw);
    			NBServer.out.println (lw);
    			NBServer.out.flush();
    
    			// se imprime el resultado de la consulta
    			if(rs1.next())
    				writer.println(rs1.getString(2));
    			else
    				writer.println("No se encontro la palabra");
    		}
    		catch(Throwable e){
    			e.printStackTrace();
    		}
    	}
    
    	// metodo para agregar un entrada al diccionario
    	public void agregarEntrada() {
    		try{
    			// si no esta la conexion  a la base de datos se crea
    			if(estSQL==null){
    				Class.forName("com.mysql.jdbc.Driver").newInstance();
    				Connection conex = DriverManager.getConnection(NBServer.conexionBase, "root", "root");
    				estSQL = conex.createStatement();
    			}
    
    			//se pide la palabra
    			writer.println("Introduce termino");
    			writer.flush();
    			String palabra = reader.readLine();
    
    			// se pide el significado
    			writer.println("Introduce el significado");
    			writer.flush();
    			String definicion = reader.readLine();
    
    			// la consulta
    			estSQL.executeUpdate("INSERT INTO entradas VALUES ('"+palabra+"', '"+definicion+"')");
    
    			//bitacora
    			String lw = "[" + (new java.util.Date()).toString() + "] IP Address: " + miSocket.getInetAddress().toString() + ":" + miSocket.getPort() + " - INSERT " + palabra;
    			System.out.println (lw);
    			NBServer.out.println (lw);
    			NBServer.out.flush();
    		}
    		catch(Throwable e){
    			e.printStackTrace();
    		}
    	}
    
    	// metodo para editar un entrada
    	public void editarEntrada() {
    		try{
    		    // si no esta la conexion  a la base de datos se crea
    			if(estSQL==null){
    				Class.forName("com.mysql.jdbc.Driver").newInstance();
    				Connection conex = DriverManager.getConnection(NBServer.conexionBase, "root", "root");
    				estSQL = conex.createStatement();
    			}
    
    			//se pide la palabra
    			writer.println("Introduce termino");
    			writer.flush();
    			String palabra = reader.readLine();
    
    			// se saca el contenido actual
    			ResultSet rs1 = estSQL.executeQuery("SELECT palabra, definicion FROM entradas WHERE palabra='"+palabra+"'");
    
    			// se imprime el significado actual
    			if(rs1.next()){
    				writer.println("Significado actual:");
    				writer.println(rs1.getString(2)+"\n");
    				writer.println("Introduce nuevo significado");
    				writer.flush();
    			}
    			else
    				writer.println("No se encontro la palabra");
    
    		    // se pide el nuevo significado
    			String definicion = reader.readLine();
    
    			// se guarda en la base de datos
    			estSQL.executeUpdate("UPDATE entradas SET definicion ='"+definicion+"' WHERE palabra='"+palabra+"'");
    			String lw = "[" + (new java.util.Date()).toString() + "] IP Address: " + miSocket.getInetAddress().toString() + ":" + miSocket.getPort() + " - UPDATE " + palabra;
    			System.out.println (lw);
    			NBServer.out.println (lw);
    			NBServer.out.flush();
    		}
    		catch(Throwable e){
    			e.printStackTrace();
    		}
    	}
    
    	// metodo para eliminar un palabra
    	public void eliminarEntrada() {
    		try{
    			// si no esta la conexion  a la base de datos se crea
    			if(estSQL==null){
    				Class.forName("com.mysql.jdbc.Driver").newInstance();
    				Connection conex = DriverManager.getConnection(NBServer.conexionBase, "root", "root");
    				estSQL = conex.createStatement();
    			}
    
    			// se pide la palabra a eliminar
    			writer.println("Introduce termino");
    			writer.flush();
    			String palabra = reader.readLine();
    
    			// se ejecuta la query
    			estSQL.executeUpdate("DELETE FROM entradas WHERE palabra='"+palabra+"'");
    		    writer.println("La palabra ha sido terminada");
    			String lw = "[" + (new java.util.Date()).toString() + "] IP Address: " + miSocket.getInetAddress().toString() + ":" + miSocket.getPort() + " - DELETE " + palabra;
    			System.out.println (lw);
    			NBServer.out.println (lw);
    			NBServer.out.flush();
    
    		}
    		catch(Throwable e){
    			e.printStackTrace();
    		}
    
    	}
    
    }

Cliente:

  • Lenguaje: C# (.NET)
  • Plataforma: Windows
  • Código:
  • //librerias de .NET a usar
    using System;
    using System.Net.Sockets;
    using System.IO;
    
    class csharp_client {
        public static void Main(string[] args) {
            try{
    
                // se pide información al cliente
                    // ip del servidor
                Console.WriteLine("Dame el IP del servidor");
                string ipServ = Console.ReadLine();
                    // puerto al que sea desea conectar
                Console.WriteLine("Dame el puerto a conectarse");
                int puerto = Int32.Parse(Console.ReadLine());
    
                // se crea el cliente TCP dando la ip y el puerto del servidor
                TcpClient tc=new TcpClient(ipServ,puerto);
                Console.WriteLine("Server invoked");
    
                //se obtiene el flujo de bits y se crear los streams
                //de lectura y de escritura para la comunicación
                NetworkStream ns=tc.GetStream();
                StreamWriter sw=new StreamWriter(ns);
                StreamReader sr=new StreamReader(ns);
    
                // se escribe el registro en el archivo de texto
                TextWriter tw = new StreamWriter("NBClientLog" + GetTime() + ".txt");
                tw.WriteLine(DateTime.Now + " Conectado a " + ipServ + ":" + puerto);
    
                // menú de opciones del cliente para el ABC del diccionario
                string condicion = "";
                while(condicion!="5"){
    
                    do
                    {
                        // se lee el flujo del servidor y se imprime
                        Console.WriteLine(sr.ReadLine());
                    } while (sr.Peek() != -1);
    
                    // se lee la opción del cliente
                    condicion = Console.ReadLine();
    
                    // se pasa este selección al servidor
                    sw.WriteLine(condicion);
                    sw.Flush();
    
                    // se escribe la opción seleccionada en el registro
                    switch (condicion)
                    {
                        case "1":
                            tw.Write("\r\n" + DateTime.Now + " Consulta");
                            break;
                        case "2":
                            tw.Write("\r\n" + DateTime.Now + " Alta");
                            break;
                        case "3":
                            tw.Write("\r\n" + DateTime.Now + " Edicion");
                            break;
                        case "4":
                            tw.Write("\r\n" + DateTime.Now + " Borrado");
                            break;
                        case "5":
                            tw.Write("\r\n" + DateTime.Now + " Desconexion");
                            break;
                        default:
                            tw.Write("["+condicion+"]");
                            break;
                    }
    
                }
    
                tw.Close();
    
            }catch(Exception e){Console.WriteLine(e);}
    
        }
    
        // método para la obtención de la fecha para el registro
        private static Int64 GetTime() {
           Int64 retval=0;
           DateTime st= new DateTime(1970,1,1);
           TimeSpan t= (DateTime.Now-st);
           retval = (Int64)(t.TotalMilliseconds + 0.5);
           return retval;
        } 
    
    }
  1. #1 by leciarkluggug on 21/05/2010 - 10:45 am

    Just want to say what a great blog you got here!
    I’ve been around for quite a lot of time, but finally decided to show my appreciation of your work!

    Thumbs up, and keep it going!

    Cheers
    Christian, iwspo.net

  2. #2 by LomoPymnsleem on 21/05/2010 - 4:48 pm

    Thank you – I liked this post. Anyway the time will pass and we will see if you are right or not. Have a nice day and regards from New Zeland!
    Chris
    My site

  3. #3 by JohnLBA on 24/05/2010 - 3:27 am

    It’s very good article.

  4. #4 by odymar pardo on 24/05/2010 - 11:44 pm

    Que bueno si colocaras el script de la base de datos o el archivo plano ipsql.txt,para correr la aplicacion y chequear y analizar su contenido como estudiante de ingenieria de sistemas creo que seria un buen aporte

  5. #5 by buy xanax on 26/05/2010 - 11:48 am

    That’s a very interesting point of view. I didn’t know about it. Keep developing your site, bro!

  6. #6 by buy valium on 27/05/2010 - 6:21 am

    I would like to express my appreciation for your post. That’s really great to know that there are such people like you who do their job very well and with such enthusiasm.

  7. #7 by tramadol on 27/05/2010 - 2:50 pm

    I don’t agree. But still good post.

  8. #8 by dTemielamy on 01/06/2010 - 5:41 am

    Thank you very well read all textt about drsang and ilike it very much

  9. #9 by buy phentermine on 05/06/2010 - 9:10 am

    Thank you for your work. I have bookmarked your site and I will definitely read your other posts. Thanks again.

  10. #10 by levitra online on 07/06/2010 - 4:13 am

    That’s a very interesting topic for discussing. Who wants to argue?

  11. #11 by togedenjin on 16/06/2010 - 11:22 pm

    The dear author, thanks you for a vital topic!

  12. #12 by Cialisbalaba on 17/06/2010 - 2:46 am

    I am pleased with your blog, I think we have a lot in common. I’ll go to you on more often Cialis cool.

  13. #13 by soft-7.com on 19/06/2010 - 7:42 am

    I learned something from this important post. That is the way, I want to thank you.

  14. #14 by derministr on 22/06/2010 - 12:19 pm

    Thanks, now at each useful theme are the blog))

  15. #15 by Buy Xanax on 24/06/2010 - 6:14 pm

    Hey bro! You are the best. Keep doing your job in the same way.

  16. #16 by Acers on 06/07/2010 - 8:01 am

    Fue a pie de vela por neto y me encontré con su sitio web, usted escribe muy bien. reciprocar la visita de mi El sitio web. http://notebooksacer.blogspot.com

  17. #17 by zverin on 08/07/2010 - 12:54 pm

    I want to quote your post in my blog. It can?
    And you et an account on Twitter?

  18. #18 by tramadol on 08/07/2010 - 1:35 pm

    Hello everyone. I beleive this disscussion requires more intellectual opinions to be more interesting. But, of course, the author made a great job!

  19. #19 by buy cialis on 08/07/2010 - 7:42 pm

    Intellectual??? That was the most “intellectual” comment I’ve ever seen. LOL

  20. #20 by SarahWinters on 08/07/2010 - 8:56 pm

    Thank you so much for such a great and inspiring post!

  21. #21 by Jonatan on 10/07/2010 - 10:36 am

    yeah, you can post it on your blog, second we don’t have a Twitter account

(No será publicado)