Benemérita Universidad Autónoma de Puebla Materia: Programación Distribuida. Catedrática: M.C. Maria del Carmen Ceron Garnica Proyecto: *Simulación Terminal de camiones * Venta y Recepción de Boletos Presenta: Camela Reyes Armando Cruz Espinal Gabriel García Cérquela Natanael Maratinez Martinez Claudio Norberto Nieves Zúñiga Eleazar Ingeniería en Ciencias de la Computación Facultad de Ciencias de la Computación. Heroica puebla de Zaragoza, puebla a Julio del 2007 INDICE CAPITULO 1: INTRODUCCION Y OBJETIVOS 1.1 Introducción………………………………………………………………...…3 1.2 Objetivos 1.21 Objetivo general……………………………………………………………...4 1.22 Objetivo especifico…………………………………………………………...5 CAPITULO 2: DESARROLLO 2.1Desarrollo teórico 2.11Interfaz………………………………………………………………………...7 2.12 Diseño de clases……………………………………………………………..10 2.13 Relaciones……………………………………………………………………11 2.2Desarrollo practico 2.21 Código de la aplicación Ticket Bus Servidor………….……………………..15 2.22 Código Fuente de la aplicación Ticket Bus Estación de trabajo.....................19 2.23Código Fuente de la aplicación Ticket Bus Cliente…………………………...22 2.24 Interfaz final…………………………………………………………………..25 CAPITULO 3: Anexos Conclusiones……………………………………………………………….………27 Bibliografía……………………………………………………………………..….28 **** CAPITULO 1 **** Introducción El sistema que se desarrollara surgió como un proyecto a corto plazo para la materia de Programación Concurrente y tiene como finalidad la creación de un sistema en el lenguaje de programación JAVA que maneje una Terminal de autobuses. Este sistema pretende que cualquier usuario pueda manejarlo por lo que tiene que ser sencillo, y gozar de una buena interfase. En el apartado de objetivos se hará mención de los logros que se pretende conseguir con la realización de dicho sistema. Objetivo general Se persigue primordialmente el fin de realizar un software de “Terminal de autobuses” que sea manejable para cualquier usuario, sin importar edad, sexo o status social y que tenga el cometido de permitir que el usuario consulte de entre una base de datos un destino deseado, en esa consulta debe aparecer el precio del boleto y el sistema debe de ser capaz de venderlo, además de permitir que el usuario escoja un asiento. Objetivos específicos Nuestro sistema tiene como objetivos específicos los siguientes: El sistema debe manejar 10 destinos distintos, especificados por un color. El sistema debe manejar 4 salas de espera y mandar a los usuarios a ella antes de abordar el camión de su destino. Los usuarios que aborden un camión desaparecerán de la sala de espera y sus lugares en ella serán reasignados a nuevos usuarios. Un usuario ira a la sala de espera que según se indique en su destino como sur, norte, este u oeste. El sistema debe gozar de una interfase sencilla y practica para evitar que algún usuario se desespere por su funcionamiento. El sistema debe ser capaz de permitir la venta de boletos a usuarios y evitar que dos usuarios quieran acceder a la misma información a la vez para evitar un traslape de lugares en el autobús o una posible sobrecarga de boletos. **** CAPITULO 2 **** Primera Interfaz propuesta En la figura numero 1 se muestra la interfaz principal del sistema que consta de información sobre la disponibilidad de cupo en las salas que se dividieron en 4, una para los destinos del sur (Tabasco y Oaxaca), otra para los destinos del norte (Monterrey, Guadalajara y Tijuana), otra para los destinos del este (Veracruz y Tlaxcala) y finalmente una para los destinos del oeste (Guerrero y Colima). Cada destino fue marcado con un color de la manera siguiente: Así, se ubicaran los lugares en la sala de forma aleatoria y según el color se sabrá el destino al que pertenece. Posteriormente existen dos opciones, la de consulta y la de Comprar boleto, si se da clic en consulta aparece del lado derecho una ventana de información en donde el usuario elegirá de la lista el destino a elegir, a continuación aparecerá información como las horas de salida de los camiones y el precio del boleto, junto con una pequeña imagen del destino. La figura 1 se muestra a continuación: Ahora, si el usuario se decide y quiere comprar su boleto usara la opción de “comprar boleto” que despliega una nueva ventana que se muestra en la figura 2. En esta nueva ventana el usuario elegirá el destino al que desea ir y se mostrara el precio del boleto, junto con los lugares disponibles en el autobús. Si el usuario se decide podrá ver que lugares de los que están disponibles, para ello se maneja una pequeña imagen que simula los asientos del autobús y que utiliza dos símbolos para indicar si el asiento esta disponible u ocupado, estos signos son: Si el asiento escogido esta marcado de verde no podrá usarlo, pero si esta marcado de rojo si podrá usarlo. Si cambia de opinión o tuvo algún error y no quiere viajar simplemente da la opción “cancelar”. La figura numero 2 es la siguiente: Relación usuario – boleto. Relación usuario – cliente. Relación usuario –autobús. Relaciones. Usuarios = Cliente 1 Cliente =1 Boleto = 1 Autobús 1 Boleto = 1 Asiento = 1 Autobús Código Fuente de la aplicación Ticket Bus Servidor import java.awt.*; import java.net.*; import java.sql.*; import java.io.*; import java.awt.event.*; import java.util.Vector; public class tbServer extends Frame{ ServerSocket s; //el socket de la conexion int clientes; // cantidad de clientes concectados int lugares[]; //lugares reservados TextArea entrada; //area de escritura de mensajes Connection cntn; //Manejador para ODBC (conexion con acces) Statement stmt; //Para maejar las consultas ResultSet rslt; //tabla de resultados tbServer(){ //************DECLARACIONES PARA LA BASE DE DATOS *************** try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //para ocupar los ODBC de la maquina cntn = DriverManager.getConnection("jdbc:odbc:BaseDatos"); //para accesar a la base de datos stmt = cntn.createStatement(); //para crear una interfaz con la BD } catch (Exception e) {}; //************DECLARACIONES PARA EL FRAME SERVIDOR ************** lugares=new int[5]; //un arreglo de 5 lugares setTitle("Servidor de TicketBus"); //titulo de la ventana setBackground(Color.blue); //color del fondo (no se ve...) setSize(550,350); //tamaño del frame entrada=new TextArea(20,40); //area de texto entrada.setEditable(false); //no se puede modificar add(entrada); addWindowListener(new Cerrar()); //para cuando se cierra la ventana setVisible(true); clientes=0; } class Cerrar extends WindowAdapter{ public void windowClosing(WindowEvent e){ try{stmt.close(); //cierra el statement cntn.close();} //cierra la conexion con ODBC catch (Exception ex) {}; dispose(); System.exit(0); } } public void añadir(String texto){ entrada.append(texto); } void lanzarServidor(){ String cadena; try{ s=new ServerSocket(5000,50); //crea el socket servidor en puerto 5000, con un maximo de 50 clientes while(true){ new NuevoCliente(s.accept(),this,clientes++).start(); //acepta las peticiones de conexion } } catch(IOException e) {}; } void reservar(String destino,String hora,String nombre,int cantidadA){ //para cuando deseo reservar un lugar String inst="Insert into Autobus values ('"+nombre+"','"+destino+"','"+hora+"','"+cantidadA+"')"; //instruccion SQL para añadir a la BD los datos que le mando try{ stmt.executeUpdate(inst); //ejecuto la inserccion en la BD añadir("Se han reservado "+cantidadA+" lugares mas\n"); //escribe un mensaje en el servidor } catch(Exception e) {}; } boolean consultar(String destino,String hora,int cantidadA){ //para saber si hay o no lugares disponibles int suma=0; try{ añadir("Realizando Consulta...\n"); rslt = stmt.executeQuery("SELECT * FROM Autobus where Ruta like '"+destino+"' and Hora like '"+hora+"'"); //instruccion SQL para consultar en BD los registros para un autobus determinado añadir("consulta terminada, hay a la fecha: "); while (rslt.next()){ //mientras haya mas registros de respuesta int temp=rslt.getInt("CantidadAR"); //obtiene la cantidad de asientos reservados para cada uno suma=suma+temp; //y los suma } //añadir(Integer.toString(suma)+" lugares apartados\n"); if ((suma+cantidadA)<45){ //si aun hay lugares disponibles return true; //regresa verdadero } else return false; // o falso de lo contrario } catch (Exception e) {añadir("ERROR! CONSULTA INVALIDA!\n");}; return false; } String buscar(String nombre){ //para saber si alguien ya ha reservado Vector aux=new Vector(); try{ rslt = stmt.executeQuery("SELECT * FROM Autobus WHERE Nombre LIKE '"+nombre+"'"); //consulta SQL en base al nombre while(rslt.next()){ //mientras haya registros que coincidan String ayuda=rslt.getString("Ruta")+" "+rslt.getString("Hora")+" "+rslt.getString("CantidadAR")+"°"; //obtiene los datos de cada regitro y los guarda en una cadena añadir(ayuda+"\n"); aux.addElement(ayuda); //la cadena la añade a un vector } }catch (Exception e) {}; return aux.toString(); //regrea el vector en forma de cadena } public static void main(String args[]){ tbServer Servidor=new tbServer(); Servidor.lanzarServidor(); } } class NuevoCliente extends Thread{ Socket conexion; tbServer serv; int cliente; DataInputStream entrada; //flujo de entrada de datos DataOutput salida; //flujo de salida de datos NuevoCliente(Socket c,tbServer s,int numero){ conexion=c; serv=s; cliente=numero; try{ entrada=new DataInputStream(conexion.getInputStream()); salida=new DataOutputStream(conexion.getOutputStream()); } catch (IOException e) {}; } public void run(){ boolean Salir=false; while(!Salir){ //mientras no de la instruccion salir en la terminal try{ String destino=entrada.readUTF(); //lee una cadena en teoria, la ruta de viaje if (destino.equals("Salir")) //si el texto es el de salir, termina la ejecucion Salir=true; else{ if (destino.equals("Terminal")||destino.equals("Station")) //si dice Terminal o Station, lo conecta y se prepara para lo que sigue serv.añadir("Conectando "+destino+"\n"); else{ if (destino.charAt(0)=='>') //si el texto comienza con > (es de la telefonista) { destino=destino.substring(1); //borra del destino el caracter > String hora=entrada.readUTF(); //lee la hora String nombre=entrada.readUTF(); //lee el nombre del registro int casientos=Integer.parseInt(entrada.readUTF()); //lee la cantidad de asientos que desean reservar serv.añadir("Intentando reservar un pasaje "+destino+" "+hora+"\n"); if(serv.consultar(destino,hora,casientos)){ //si aun hay asientos salida.writeUTF("Reservacion completada "); //dice que ya reservo serv.reservar(destino,hora,nombre,casientos); //reserva } else salida.writeUTF("No hay Lugares Disponibles"); //si no, dice que ya no hay lugares } else{ //si el texto no comienza con > String datos=serv.buscar(destino); //busca los datos de los que reservaron a ese nombre salida.writeUTF(datos); //los envia a la station } } } } catch (IOException e) {}; } serv.añadir("La terminal ha sido desconectada\n"); try{ conexion.close(); //cierra la conexion } catch (IOException e) {}; } } Código Fuente de la aplicación Ticket Bus Estación de trabajo import java.awt.*; import java.net.*; import java.io.*; import java.util.StringTokenizer; import java.awt.event.*; class tbStation extends Frame implements ActionListener{ Socket conexion; DataOutputStream salida; DataInputStream entrada; Panel panel; Button consulta,conectar,desconectar; TextArea estado; TextField nombre,casientos,opcionViaje,opcionHora; tbStation(){ super("TicketBus Estación Central"); //titulo de la ventana // setBackground(Color.LIGHT_GRAY); //colores setBackground(Color.black); //colores setForeground(Color.red); setSize(300,460); panel=new Panel(); nombre=new TextField(25); estado=new TextArea(15,35); nombre.setEnabled(true); estado.setEnabled(false); consulta=new Button("Consultar"); consulta.setEnabled(false); conectar=new Button("Conectar"); desconectar=new Button("Desconectar"); desconectar.setEnabled(false); panel.add(new Label(" CONSULTA DE RESERVACION ")); panel.add(new Label("NOMBRE DE REGISTO: ")); panel.add(nombre); panel.add(consulta); panel.add(estado); panel.add(new Label("OPCIONES DE CONEXION")); panel.add(conectar); panel.add(desconectar); consulta.addActionListener(this); //escucha para el boton consulta conectar.addActionListener(this); //escucha para el boton conectar desconectar.addActionListener(this); // " " " " desconectar addWindowListener(new Cerrar()); add(panel); setVisible(true); } public void actionPerformed(ActionEvent e){ String com=e.getActionCommand(); if(com.equals("Consultar")){ //si el boton presionado es el de Consultar try { salida.writeUTF(nombre.getText()); //escribe en el servidor el nombre String datos=entrada.readUTF(); //lee los registros que le manda el servidor (un vector en forma de cadena) StringTokenizer cad=new StringTokenizer(datos,"[],°"); //lo separa en base a los caracteres del vector y un caracter predefinido while (cad.hasMoreTokens()){ //mientras haya tokens estado.append(cad.nextToken()+"\n"); //los escribe } nombre.setText(""); //borra el nombre consultado } catch(IOException excepcion) {}; } else if (com.equals("Conectar")){ //si el boton es el de conectar try{ conexion=new Socket(InetAddress.getLocalHost(),5000); //obtiene el servidor salida=new DataOutputStream(conexion.getOutputStream()); //crea las conexiones entrada=new DataInputStream(conexion.getInputStream()); salida.writeUTF("Station"); //escribe en el servidor Station para identificarlo conectar.setEnabled(false); //cambia las propiedades de los botones consulta.setEnabled(true); desconectar.setEnabled(true); } catch (IOException excepcion) {}; } else try{ salida.writeUTF("Salir"); //si no, (es el de salir) conexion.close(); //cierra la conexion conectar.setEnabled(true); //cambia las propiedades de los botones desconectar.setEnabled(false); conectar.setEnabled(false); } catch(IOException excepcion) {}; } class Cerrar extends WindowAdapter{ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } } public static void main(String args[]){ new tbStation(); } } Código Fuente de la aplicación Ticket Bus Cliente import java.awt.*; import java.net.*; import java.io.*; import java.awt.event.*; class tbClient extends Frame implements ActionListener{ Socket conexion; Choice opcionViaje, opcionHora; DataOutputStream salida; //buffer de salida DataInputStream entrada; //buffer de entrada Panel panel; Button reservar,conectar,desconectar; TextField estado,nombre, casientos; tbClient(){ //creacion de la ventana (para mas datos, chacar las otras clases) super("TicketBus Telephonical Center"); setBackground(new Color (255,182,123)); setForeground(Color.black); setSize(220,350); panel=new Panel(); nombre=new TextField(25); estado=new TextField(25); casientos=new TextField(10); nombre.setEnabled(true); estado.setEnabled(false); opcionViaje=new Choice(); opcionHora=new Choice(); opcionViaje.add("Puebla -> Veracruz"); opcionViaje.add("Puebla -> Mexico"); opcionViaje.add("Puebla -> Tlaxcala"); opcionViaje.add("Puebla -> Oaxaca"); opcionViaje.add("Puebla -> Hidalgo"); opcionViaje.setEnabled(false); opcionHora.add("7:00 hrs"); opcionHora.add("9:00 hrs"); opcionHora.add("11:00 hrs"); opcionHora.add("13:00 hrs"); opcionHora.add("15:00 hrs"); opcionHora.add("17:00 hrs"); opcionHora.add("19:00 hrs"); opcionHora.setEnabled(false); reservar=new Button("Reservar"); reservar.setEnabled(false); conectar=new Button("Conectar"); desconectar=new Button("Desconectar"); desconectar.setEnabled(false); panel.add(new Label("RUTA DE VIAJE")); panel.add(opcionViaje); panel.add(opcionHora); panel.add(new Label("NOMBRE DE REGISTRO: ")); panel.add(nombre); panel.add(new Label("CANTIDAD DE ASIENTOS: ")); panel.add(casientos); panel.add(reservar); panel.add(new Label("OPCIONES DE CONEXION")); panel.add(conectar); panel.add(desconectar); panel.add(estado); reservar.addActionListener(this); conectar.addActionListener(this); desconectar.addActionListener(this); addWindowListener(new Cerrar()); add(panel); setVisible(true); } public void actionPerformed(ActionEvent e){ String com=e.getActionCommand(); if(com.equals("Reservar")){ //si se presiona el boton reservar try { salida.writeUTF(">"+opcionViaje.getItem(opcionViaje.getSelectedIndex())); //escribe en el servidor la ruta del viaje con un > al principio salida.writeUTF(opcionHora.getItem(opcionHora.getSelectedIndex())); //escribe la hora salida.writeUTF(nombre.getText()); //escribe al servidor el nombre salida.writeUTF(casientos.getText()); //escribe la antidad de asientos String lugares=entrada.readUTF(); //lee la descricion de si hay o no lugares disponibles estado.setEnabled(true); estado.setText(lugares); estado.setEnabled(false); } catch(IOException excepcion) {}; } else if (com.equals("Conectar")){ //si presionan el boton Conectar try{ conexion=new Socket(InetAddress.getLocalHost(),5000); //crea el socket y busca la conexion con el servidor local salida=new DataOutputStream(conexion.getOutputStream()); //abre los flujos de entrada/salida entrada=new DataInputStream(conexion.getInputStream()); salida.writeUTF("Terminal"); //escribe al servidor Terminal para identificarse conectar.setEnabled(false);//cambia las propiedades de los botones desconectar.setEnabled(true); reservar.setEnabled(true); opcionViaje.setEnabled(true); opcionHora.setEnabled(true); } catch (IOException excepcion) {}; } else try{ salida.writeUTF("Salir"); //para salir, cerrar la conexion, etc... conexion.close(); conectar.setEnabled(true); desconectar.setEnabled(false); reservar.setEnabled(false); opcionViaje.setEnabled(false); opcionHora.setEnabled(false); } catch(IOException excepcion) {}; } class Cerrar extends WindowAdapter{ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } } public static void main(String args[]){ new tbClient(); } } Interfaz final Interfaces de las aplicaciones antes mencionadas. · Interfaz cliente · Interfaz Estación · Interfaz Servidor **** CAPITULO 3 **** Anexos Conclusiones Con lo abordado en el presente trabajo se puede decir que el analizar el problema antes de llevarlo a la practica es sumamente importancia, pues gracias a ello se pudo contemplar las posibles soluciones a los problemas que podríamos tener mas adelante y ahorrarnos muchos pasos innecesarios a la hora de la codificación, al principio fue mas tardado pero nos ayudo mucho. Aprendimos el uso de los threads y reafirmamos conocimientos adquiridos tanto en el curso como en otros cursos. Desarrollar un sistema de Terminal de autobuses no fue una tarea sencilla y conforme se iba avanzando surgían mas preguntas y queríamos buscar maneras de solucionarlas, pero se acomplejaba el sistema. En fin, podemos concluir que se lograron los objetivos planeados en un inicio y nuestro sistema cubrió las expectativas del grupo. Bibliografía Java Para Estudiantes Bell, Doug, 1944México, D.F. : Pearson Education, c2003. Programación Multithread En Java Lewis, Bil. Madrid : Pearson Education , 2003. Estructuras De Datos Y Algoritmos En Java/B Michael Goodrich, Roberto Tamassia. Goodrich, Michael T. Mexico : CECSA, c2002. Teach Yourself Java 1.1 Programming In 24 Hours. Cadenhead, Rogers. México: Prentice-Hall Hispanoamericana, 1998.