En este artículo vemos el código necesario para crear un esquema Cliente-Servidor-Servidor utilizando el protocolo TCP, realizado en Java utilizando varios Sockets.
Cómo ya sabéis el protocolo TCP está orientado a conexión, para más información podéis ver este link.
Información general de la Wikipedia:
Socket Wikipedia
Socket TCP
En el ejemplo el cliente va a llamar a un servidor que llamará al otro, como si fuese una cadena. Después el último devolverá la respuesta al anterior y el anterior al cliente inicial.
El funcionamiento sería así:
– El cliente se conecta con el servidor A.
– El servidor A transmite la petición del cliente al servidor B.
– El servidor B envía su respuesta al servidor A.
– El servidor A transfiere la respuesta del servidor A al cliente.
Código del Servidor A:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | import java.net.*; //Importa la libreria java.net import java.io.*; //Importa la libreria java.io public class servidortcp { //se declara una clase de nombre servidortcp public static void main(String argv[]) { //Se declara el método principal main que espera un parámetro System.out.println("SERVIDOR"); ServerSocket socket; //Se crea un objeto de ServerSocket //boolean fin = false; //Se declara una variable booleana inicializada a false try { //Abrimos una exceptción para el tratamiento de errores //Creamos un servidor socket = new ServerSocket(6004); //Abre un socket en modo escucha en el puerto 6001 Socket socket_cli = socket.accept(); //Inicio.Se acepta la conexión. //Método de la clase socket para recibir datos DataInputStream in = new DataInputStream(socket_cli.getInputStream()); //Método para mandar un valor al cliente DataOutputStream out = new DataOutputStream(socket_cli.getOutputStream()); String mensaje =""; //Se inicializa la variable de string mensaje a vacío mensaje = in.readUTF(); //La variable Mensaje guarda el valor que ha mandado el cliente if (mensaje.startsWith("HELLO")) { out.writeUTF("HELLO"); } do { //Estará escuchando el mensaje sin interrupción debido a la condición (1>0) del while mensaje =""; //Se inicializa la variable de string mensaje a vacío mensaje = in.readUTF(); //La variable Mensaje guarda el valor que ha mandado el cliente if (mensaje.startsWith("ALL")) { mensaje = "ALL BUR:250;CHE:300; BIG:540; PAT:380; SAL:240; BEV:210; DIE:0; COF:0; DES:300"; System.out.println(mensaje); } else if(mensaje.startsWith("BUR")) { mensaje = "BUR 250"; System.out.println(mensaje); } else if (mensaje.startsWith("CHE")) { mensaje = "CHE 300"; System.out.println(mensaje); } else if (mensaje.startsWith("BIG")) { mensaje= "BIG 540"; System.out.println(mensaje); } else if (mensaje.startsWith("PAT")) { mensaje= "PAT 380"; System.out.println(mensaje); } else if (mensaje.startsWith("SAL")) { mensaje= "SAL 240"; System.out.println(mensaje); } else if (mensaje.startsWith("BEV")) { mensaje= "SAL 210"; System.out.println(mensaje); } else if (mensaje.startsWith("DIE")) { mensaje= "DIE 0"; System.out.println(mensaje); } else if (mensaje.startsWith("COF")) { mensaje= "COF 0"; System.out.println(mensaje); } else if (mensaje.startsWith("DES")) { mensaje= "DES 300"; System.out.println(mensaje); } else if (mensaje.startsWith("fin")) { mensaje= "fin"; System.out.println(mensaje); } else{ mensaje = "ERROR"; System.out.println(mensaje); } //Mandamos al cliente la respuesta de las calorias según lo que ha mandado out.writeUTF(mensaje); //System.out.println(mensaje); } while (1>0); } catch (Exception e) { //Si se produce algún error saltará la excepción con el mensaje de error System.err.println(e.getMessage()); System.exit(1); //Salimos con error } } } |
Código del Servidor B:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | import java.net.*; //Importa la libreria java.net import java.io.*; //Importa la libreria java.io public class servidor3tcp { public static void main(String argv[]) { //Se declara el método principal main que espera un parámetro //Cuando se indica el servidor2 se hace refencia a servidortcp.java //Declaración de variables necesarias Socket socket; //Se crea un objeto de ServerSocket InetAddress address; //Se crea un objeto de tipo InetAddress ServerSocket socket3; //Se crea un objeto de ServerSocket String mensaje ="HELLO"; //Se usará para comunicarse con el cliente String mensajeServidor=""; //Se usará para almacenar el resultado obtenido del servidor2 String mensajeServidor2=""; //Se usará para almacenar el resultado obtenido del servidor2 para el pedido2 String mensaje3=""; //Almacenará el resultado final enviado al cliente String CaloriaPedido2=""; //Contendrá las calorias del pedido 2 String CaloriaPedido1=""; //Contendrá las calorias del pedido 1 //Otras variables para calcular la suma de calorias int longMensaje; //En esta variable se almacenará el tamaño del mensaje String Pedido1=""; //Guardará el string del pedido 1 String Pedido2=""; //Guardará el string del pedido 2 //Guardará el valor de las calorias y el total. Pos y Pos1 indicarán la posición //donde habrá que empezar para contar las cadena recibida int iCaloriaPeiddo2, iCaloriaPeiddo1, iTotalCalorias, pos, pos1=0; try { //Dirección del servidor address=InetAddress.getByName(argv[0]); //Creamos un servidor para el cliente socket = new Socket(address,6004); DataInputStream in = new DataInputStream(socket.getInputStream()); DataOutputStream out = new DataOutputStream(socket.getOutputStream()); //Mandamos el saludo al servidor2 out.writeUTF("HELLO"); //Recojemos el resultado del servidor2 mensajeServidor = in.readUTF(); System.out.println(mensajeServidor); //Creamos el socket "servidor" para comunicarnos con el cliente socket3 = new ServerSocket(6001); //Aceptamos la conexión al servidor2 y nos preparamos para recibir datos suyos Socket socketClient = socket3.accept(); DataInputStream in2 = new DataInputStream(socketClient.getInputStream()); DataOutputStream out2 = new DataOutputStream(socketClient.getOutputStream()); //Leemos del cliente esperando el saludo inicial mensaje = in2.readUTF(); if (mensaje.startsWith("HELLO")) out2.writeUTF("HELLO"); do { //Estará escuchando el mensaje sin interrupción debido a la condición (1>0) del while mensaje = in2.readUTF(); System.out.println(mensaje); //Limpiamos las variables utilizadas. iCaloriaPeiddo2=0; iCaloriaPeiddo1=0; longMensaje=0; //Para separar las dos descipciones calcularemos el tamaño de la cadena //y buscaremos un espacio que las separa, después cogeremos la segunda cadena //emepzando por la posición +1, para poder saltar el espacio en blanco longMensaje = mensaje.length(); pos= mensaje.indexOf(' '); if (pos > 0) { //Si es mayor que cero se han recibido dos palabras //Separamos el contenido enviado para calcular la suma de calorias //Obtenemos la descripción de los dos pedidos //Segundo pedido Pedido2 = mensaje.substring(pos+1, longMensaje); //Primer pedido Pedido1 = mensaje.substring(0,pos); //Calculamos las calorias del pedido2 out.writeUTF(Pedido2); //Recogemos el resultado del servidor2 mensajeServidor2 = in.readUTF(); //Se calcula el tamaño del resultado del Pedido2 longMensaje = mensajeServidor2.length(); pos1= mensajeServidor2.indexOf(' '); if ((pos1 < 0) || mensajeServidor2.startsWith("ERROR") || mensajeServidor2.startsWith("ALL")){ //Si se ha recibido del servidor2 la palabra error, o la palabra ALL, las calorias serán 99999 CaloriaPedido2 = "ERROR"; mensajeServidor2 = Pedido2 + " " + "ERROR"; iCaloriaPeiddo2 = 9999; } else{ //Separamos las calorias del pedido2 CaloriaPedido2 = mensajeServidor2.substring(pos1+1, longMensaje); //Valor numérico de las calorias del pedido2 iCaloriaPeiddo2 = Integer.parseInt(CaloriaPedido2.trim()); } //Calculamos las calorias del pedido1 //Le mandamos al servidor2 el literal del Pedido1 out.writeUTF(Pedido1); //Obtenemos el resultado del servidor2 mensajeServidor = in.readUTF(); //Se calcula el tamaño del resultado del Pedido1 longMensaje = mensajeServidor.length(); pos1= mensajeServidor.indexOf(' '); if ((pos1 < 0) || mensajeServidor.startsWith("ERROR") || mensajeServidor.startsWith("ALL")){ //Si se ha recibido del servidor2 la palabra error, o la palabra ALL las calorias serán 99999 CaloriaPedido1 = "ERROR"; mensajeServidor = Pedido1 + " " + "ERROR"; iCaloriaPeiddo1 = 9999; } else{ //Separamos las calorias del pedido1 CaloriaPedido1 = mensajeServidor.substring(pos1+1, longMensaje); //Valor numérico de las calorias del pedido1 iCaloriaPeiddo1 = Integer.parseInt(CaloriaPedido1.trim()); } //Calculamos el total de las calorias if(iCaloriaPeiddo2 == 9999 || iCaloriaPeiddo1 == 9999){ //Si uno de los dos pedidos es erroneo el total de calorias será 9999 iTotalCalorias = 9999; } else iTotalCalorias = iCaloriaPeiddo1 + iCaloriaPeiddo2; System.out.println(mensajeServidor); System.out.println(mensajeServidor2); //Se crea el mensaje final con los dos pedidos y la suma de sus calorias. mensaje3 = Pedido1 + " " + Pedido2 + " " + iCaloriaPeiddo1 + " " + iCaloriaPeiddo2 + " = " + iTotalCalorias; //Imprimimos en el servidor3 el total System.out.println(mensaje3); //Le mandamos al cliente el total de calorias de los dos productos. out2.writeUTF(mensaje3); } else{ //Si es menor que 0 solo se habrá recibido una palabra //Le mandamos al servidor2 la descripción out.writeUTF(mensaje); //Recojemos del servidor2 el resultado mensajeServidor = in.readUTF(); System.out.println(mensajeServidor); //Le mandamos al cliente el resultado que nos ha dado el servidor2 out2.writeUTF(mensajeServidor); } } while (1>0); } catch (Exception e) { //Si se produce algún error saltará la excepción con el mensaje de error System.err.println(e.getMessage()); System.exit(1); //Salimos con error } } } |
Código del Cliente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | import java.net.*; //Se importa la libreria java.net import java.io.*; //Se importa la libreria java.io //Se declara la clase clientetcp public class clientetcp { //Se declara el método principal main que recibe un parámetro public static void main(String argv[]) { //Si no recibe ningún parámetro dará error if (argv.length == 0) { System.err.println("java clientetcp servidor"); System.exit(1); } System.out.println("CLIENTE"); // Se guarda en el buffer un valor introducido por pantalla BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); Socket socket=null; //Se crea un objeto de tipo socket InetAddress address; //Se crea un objeto de tipo InetAddress String mensaje=""; //Se declara una variable de tipo string try { //Se abre una excepción //Obtiene el nombre de la dirección remota del socket address=InetAddress.getByName(argv[0]); socket = new Socket(address,6001); //Se crea un objeto de tipo socket //para establecer una conexión por el puerto 6001 //Se declara un objeto de tipo DataOutputStream para mandar valores al servidor DataOutputStream out = new DataOutputStream(socket.getOutputStream()); //Se declara un objeto de tipo DataOutputStream para mandar obtener al servidor DataInputStream in2 = new DataInputStream(socket.getInputStream()); //Mandamos la palabra HELLO al servidor out.writeUTF("HELLO"); //Recogemos lo que nos devuelve el servidor y lo guardamos en la variable mensaje mensaje = in2.readUTF(); System.out.println(mensaje); //Imprime el contenido de mensaje do { //Mientras el mensaje no sea fin seguira leyendo mensaje = in.readLine(); out.writeUTF(mensaje); //System.out.println(mensaje); //Imprime el contenido de mensaje //NUEVO mensaje =""; //Se inicializa la variable de string mensaje a vacío mensaje = in2.readUTF(); System.out.println(mensaje); //Imprime el contenido de mensaje //NUEVO } while (!mensaje.startsWith("fin")); } catch (Exception e) { System.err.println(e.getMessage()); System.exit(1); } } } |