Diferencia entre revisiones de «Solucións as prácticas con Sockets TCP»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 513: Línea 513:
 
     }
 
     }
 
}
 
}
 +
 +
</syntaxhighlight>
  
 
'''ClienteAdivinaNumero.java'''
 
'''ClienteAdivinaNumero.java'''

Revisión del 15:28 25 nov 2021

Enunciado 1 - Envío de mensaxe

Crea un programa cliente/servidor:

  • O programa servidor envía unha mensaxe a outro programa cliente
  • O programa cliente devuelve a mensaxe recibida ó servidor.

Solución enunciado 1

Enunciado 2 - Duplicando número

Crea un programa cliente/servidor:

  • O programa cliente lee un entero por teclado e envíallo ó programa servidor
  • O porgrama servidor devolveralle o doble do número.
  • O cliente ten que escribir na consola tanto o número enviado como o resultado recibido (o doble).

Solución enunciado 2

Servidor:

 1 import java.io.DataInputStream;
 2 import java.io.DataOutputStream;
 3 import java.io.IOException;
 4 import java.net.ServerSocket;
 5 import java.net.Socket;
 6 
 7 public class ServidorDoble {
 8 
 9     public static void main(String[] args) {
10         ServerSocket servidor;
11         Socket socket;
12         DataOutputStream saida; //Fluxo de saída
13         DataInputStream entrada; //Fluxo de entrada
14 
15         System.out.println("Agardando polo cliente... ");
16 
17         try {
18             servidor = new ServerSocket(4000);
19             socket = new Socket();
20             socket = servidor.accept();
21             if (socket != null) {
22                 System.out.println("Conectado co cliente");
23             }
24 
25             entrada = new DataInputStream(socket.getInputStream());
26             int numero = entrada.readInt();
27 
28             saida = new DataOutputStream(socket.getOutputStream());
29             saida.writeInt(numero * 2);
30             socket.close();
31 
32         } catch (IOException e) {
33             e.printStackTrace();
34         }
35     }
36 }

Cliente:

 1 import java.io.DataInputStream;
 2 import java.io.DataOutputStream;
 3 import java.io.IOException;
 4 import java.net.Socket;
 5 import java.util.Scanner;
 6 
 7 public class ClienteDoble {
 8 
 9     public static void main(String[] args) {
10         DataOutputStream saida;
11         DataInputStream entrada;
12         Socket socket;
13         int num;
14         Scanner in = new Scanner(System.in);//Para ler da entrada estándar
15 
16         try {
17             socket = new Socket("127.0.0.1", 4000);
18             System.out.println("Conectado co servidor");
19 
20             //creanse os fluxos de entrada e saida para ler do
21             //servidor e escribir no servidor.
22             entrada = new DataInputStream(socket.getInputStream());
23             saida = new DataOutputStream(socket.getOutputStream());
24             //Lee o entero da entrada estándar
25             System.out.print("Teclea un entero ");
26             num = in.nextInt();
27             //Enviamos un entero ó servidor
28             saida.writeInt(num);
29             //Recibimos o doble do servidor.
30             int resultado = entrada.readInt();
31 
32             System.out.println("O díxito " + num + " ten como doble o " + resultado);
33             socket.close();
34 
35         } catch (IOException e) {
36             e.printStackTrace();
37         }
38     }
39 }

Enunciado 3 - Convertindo a maiúsculas

Crea un programa cliente/servidor:

  • O programa cliente lee unha cadea por teclado e envíalla a un programa servidor
  • O programa servidor devolverá a cadea convertida a maiúsculas
  • O cliente ten que escribir a cadea devolta na consola

Solución enunciado 3

Servidor:

 1 import java.io.DataInputStream;
 2 import java.io.DataOutputStream;
 3 import java.io.IOException;
 4 import java.net.ServerSocket;
 5 import java.net.Socket;
 6 
 7 public class ServidorMaiusculas {
 8 
 9     public static void main(String[] args) {
10         ServerSocket servidor;
11         Socket socket;
12         DataOutputStream saida; //Fluxo de saída
13         DataInputStream entrada; //Fluxo de entrada
14 
15         System.out.println("Agardando polo cliente,,, ");
16 
17         try {
18             servidor = new ServerSocket(4000);
19             //socket = new Socket();
20             socket = servidor.accept();
21             System.out.println("Conectado co cliente");
22 
23             //Recibe a cadea do cliente.
24             entrada = new DataInputStream(socket.getInputStream());
25             String cadea = entrada.readUTF();
26             //Devolve a cadea ó cliente pasada a maiúsculas
27             saida = new DataOutputStream(socket.getOutputStream());
28             saida.writeUTF(cadea.toUpperCase());
29             socket.close();
30 
31         } catch (IOException e) {
32             e.printStackTrace();
33         }
34 
35     }
36 }

Cliente:

 1 import java.io.*;
 2 import java.net.Socket;
 3 import java.util.Scanner;
 4 
 5 public class ClienteMaiusculas {
 6 
 7     public static void main(String[] args) {
 8         DataOutputStream saida;
 9         DataInputStream entrada;
10         Socket socket;
11         String cadea;
12         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
13         //Para ler da entrada estándar
14 
15         try {
16             socket = new Socket("127.0.0.1", 4000);
17 
18             System.out.println("Conectado co servidor");
19 
20             //creanse os fluxos de entrada e saída para leer do
21             //servidor e escribir no servidor
22             entrada = new DataInputStream(socket.getInputStream());
23             saida = new DataOutputStream(socket.getOutputStream());
24             //Lee a cadea da entrada estándar
25             System.out.print("Introduce cadea: ");
26             cadea = in.readLine();
27             //Enviamos la cadea al servidor
28             saida.writeUTF(cadea);
29             //Recibimos a cadea convertida do servidor.
30             String resultado = entrada.readUTF();
31 
32             System.out.println(cadea + " : " + resultado);
33             socket.close();
34 
35         } catch (IOException e) {
36             e.printStackTrace();
37         }
38     }
39 }

Enunciado 4 - Escaneando portos

Deseña unha sinxela aplicación Java que:

  • escanee os portos ben coñecidos (é dicir, do porto 1 ó 1024) dun determinado host
  • indica para cada porto se está aberto (se hai algunha aplicación escoitando nese orto) ou pechado.

Para iso crearase un socket:

  • se salta a excepción IOException significa que non se puido abrir o socket nese porto polo que non hai ningún proceso escoitando nel.

Unha posible saída (na que o porto 21, presumiblemente ftp, estaría aberto) sería:

... comprobando portos en ...localhost
Porto: 1 pechado
Porto: 2 pechado
...
Porto: 19 pechado
Porto: 20 pechado
Porto: 21 aberto 
Porto: 22 pechado

Solución enunciado 4

EscaneoPortos.java:

 1 import java.io.IOException;
 2 import java.net.Socket;
 3 
 4 public class EscaneoPortos {
 5 
 6     public static void main(String[] args) {
 7         String host = "localhost";
 8         System.out.println("... comprobando portos en ..." + host);
 9         for (int i = 1; i < 1024; i++) {
10             try {
11                 /*O constructor crea un socket e se logra abrilo significa que 
12                     non hai un proceso escoitando nese porto */
13                 Socket conexion = new Socket(host, i);
14                 System.out.println("Porto: " + i + " aberto ");
15             } catch (IOException ex) {
16                 /*Se hai unha excepcion significa que non se puido abrir o scoket
17                  nese porto e polo tanto non hai ningún proceso escoitando nel*/
18                 System.out.println("Porto: " + i + " pechado");
19             }
20         }
21     }
22 }

Enunciado 5 - Conectando con servidor e porto indicado

Escribe un programa cliente en java que:

  • acepta dous parámetros de entrada por consola para establecer unha conexión: o nombre dun servidor e un número de porto ó que conectar nese servidor
  • visualiza unha mensaxe por pantalla indicando se a conexión foi estrablecida ou non.
    • con conexión establecida debe amosar o número de porto e o nome do servidor co que conectou
    • con conexión fallida debe indicar o motivo dependendo do tipo de excepción acontecida:
      • "Nome de servidor descoñecido"
      • "Non é posible realizar a conexión"
  • O constructor crea un socket TCP e intenta conectalo ó host e porto remotos especificados como parámetros
  • Se o servidor DNS non está en funcionamento ou non pode resolver o nome
    • o constructor lanzará unha excepción UnknownHostException
  • Se o nome se resolve pero o socket non pode conectar por algunha outra razón (entre outras: o porto destino no servidor non está aberto, existan problemas de encamiñamento na rede para alcanzar o destino, ou simplemente o servidor especificado esté apagado):
    • lanzarase unha excepción IOException.
  • Para facilitar a depuración o programa debe comprobar se hai parámetros de entrada

Recorda que os parámetros de entrada en Java son de tipo String e que o porto no construtor Socket é un in. Porén será preciso realizar unha conversión de tipo (cast). Deste modo, se args[1] é o parámetro correspondente ó porto, a conversión pode facerse por ejemplo así:

int porto = Integer.parseInt(args[1])

Solución enunciado 5

Enunciado 6 - Factorial ou Fibonacci

Crea un programa cliente/servidor:

  • O programa cliente pida un número ó usuario por teclado e unha opción (fibonacci, factorial ou sair do programa) e envíallos ó programa servidor (se non sae do programa)
  • O programa servidor devolveralle ó cliente o resultado (factorial ou fibonacci segundo a opción escollida).
  • O cliente ten que escribir o resultado na consola.

Solución enunciado 6

Servidor:

 1 import java.io.DataInputStream;
 2 import java.io.DataOutputStream;
 3 import java.io.IOException;
 4 import java.net.ServerSocket;
 5 import java.net.Socket;
 6 
 7 public class ServidorFactorialFibo {
 8 
 9     public static void main(String[] args) {
10         ServerSocket servidor;
11         Socket socket;
12         DataOutputStream saida; //Fluxo de saida
13         DataInputStream entrada; //Fluxo de entrada
14 
15         System.out.println("Agardando polo cliente... ");
16 
17         try {
18             servidor = new ServerSocket(4000);
19             socket = servidor.accept();
20             System.out.println("Conectado co cliente");
21 
22             entrada = new DataInputStream(socket.getInputStream()); //Fluxo de entrada
23             saida = new DataOutputStream(socket.getOutputStream()); //Fluxo de saída
24 
25             //recibe opcion
26             int opcion = entrada.readInt();
27             while (opcion != 3) {// executa meentrs non reciba opción 3 (sair)
28                 System.out.println("Recibo opcion :" + opcion);
29 
30                 //Se a opción é 1 leo o nímero, calculo factorial e devólvollo ó cliente
31                 if (opcion == 1) {//recibe numero
32                     int numero = entrada.readInt();
33                     System.out.println("Recibo numero :" + numero);
34                     int resposta = factorial(numero);
35                     saida.writeInt(resposta);
36                 }
37 
38                 //Se a opcion é 2 leo o numero, calculo fibonacci e devólvollo ó cliente
39                 if (opcion == 2) {//recibe numero
40                     int numero = entrada.readInt();
41                     System.out.println("Recibo numero :" + numero);
42                     int resposta = fib(numero);
43                     saida.writeInt(resposta);
44                 }
45                 opcion = entrada.readInt();
46             }
47 
48             socket.close();
49 
50         } catch (IOException e) {
51             e.printStackTrace();
52         }
53     }
54 
55     //Reutilizamos a funcion fibonacci dos exercicios fíos
56     //fib(0)=0; fib(1)=1; fib(n)=fib(n-1)+fib(n-2)
57     public static int fib(int n) {
58         int fibonacci = 0;
59         int fibn = 0;
60         int fib0 = 0;
61         int fib1 = 1;
62         if (n == 0) {
63             fibonacci = 0;
64         } else {
65             if (n == 1) {
66                 fibonacci = 1;
67             } else {
68 
69                 for (int i = 2; i <= n; i++) {
70                     fibn = fib0 + fib1;
71                     fib0 = fib1;
72                     fib1 = fibn;
73                 }//for
74                 fibonacci = fibn; // É o último calculado
75             }//else 
76         }//else
77         return fibonacci;
78     }//fib
79 
80     //Reutilizamos a funcion factorial dos exercicios de fios    
81     public static int factorial(int n) {
82         int factorial = 1;
83         for (int i = 1; i <= n; i++) {
84             factorial = factorial * i;
85         }//for
86         return factorial;
87     }//factorial	
88 }

Cliente:

 1 import java.io.DataInputStream;
 2 import java.io.DataOutputStream;
 3 import java.io.IOException;
 4 import java.net.Socket;
 5 import java.util.Scanner;
 6 
 7 public class ClienteFactorialFibo {
 8 
 9     public static void main(String[] args) {
10         DataOutputStream saida;
11         DataInputStream entrada;
12         int num;
13         int opcion = 0;
14         Scanner in = new Scanner(System.in);//Para ler da entrada estándar
15 
16         try {
17             Socket socket = new Socket("127.0.0.1", 4000);
18             
19             System.out.println("Conectado co servidor");
20 
21             //Se cren los flujos de entrada y saida para leer del
22             //servidor y escribir en el servidor.
23             entrada = new DataInputStream(socket.getInputStream());
24             saida = new DataOutputStream(socket.getOutputStream());
25 
26             //Execútase o bucle mientras non elixamos a opcion 3 (sair).
27             while (opcion != 3) {
28                 System.out.println("\n1.- Calcular Factorial");
29                 System.out.println("2.- Calcular Fibonacci");
30                 System.out.println("3.- Sair");
31                 System.out.print("Selecciona unha opción: ");
32                 opcion = in.nextInt(); //Leo a opcion tecleada
33                 //Enviamos a opción ó servidor
34                 saida.writeInt(opcion);
35 
36                 //Facemos unha cousa ou outra segundo a opción elixida
37                 switch (opcion) {
38                     case 1: {
39                         System.out.print("Introduce número: ");
40                         //Lee o número
41                         num = in.nextInt();
42                         //Enviamos o numero ó servidor
43                         saida.writeInt(num);
44                         //Recibimos o resultado do servidor.
45                         int resultado = entrada.readInt();
46                         System.out.println("o Factorial de " + num + " é " + resultado);
47                         break;
48                     }
49                     case 2: {
50                         System.out.print("Introduce número: ");
51                         //Se lee el numero.
52                         num = in.nextInt();
53                         //Enviamos o número ó servidor
54                         saida.writeInt(num);
55                         //Recibimos o resultado do servidor
56                         int resultado = entrada.readInt();
57                         System.out.println("o Fibonacci de " + num + " é " + resultado);
58                         break;
59                     }
60                     case 3:
61                         break;
62                     default:
63                         System.out.println("Opción non válida");
64                 }
65             }
66             socket.close();
67         } catch (IOException e) {
68             e.printStackTrace();
69         }
70     }
71 }

Enunciado 7 - Adiviña o número

Crear una aplicación cliente/servidor:

  • O servidor e cliente comunícanse polo porto 6000
  • O programa servidor xenera un número aleatorio (entre 0 e 100) que será secreto.
  • O programa cliente solicita ó usuario un número e envíallo ó servidor
  • O programa servidor para cada número que lle envía o cliente indicará se:
  • e menor
  • e maior
  • acertou o número secreto e gañou
  • agotou o número de intentos (10) e perdeu

Solución enunciado 7

ServidorAdivinaNumero.java

 1 import java.io.IOException;
 2 import java.io.PrintStream;
 3 import java.net.ServerSocket;
 4 import java.net.Socket;
 5 import java.util.Random;
 6 import java.util.Scanner;
 7 import java.io.*;
 8 
 9 public class ServidorAdivinaNumero {
10 
11     public static void main(String args[]) throws IOException {
12         boolean correcto = false;
13         Random rand = new Random();
14         int numeroIntentado, sonuc, numeroAleatorio, contador = 0;
15         numeroAleatorio = rand.nextInt(100) + 1;
16         
17         System.out.println("Agardando polo cliente... ");
18 
19         ServerSocket s1 = new ServerSocket(9999);
20         Socket ss = s1.accept();
21         
22         System.out.println("Conectado co cliente!");
23         
24         Scanner sc = new Scanner(ss.getInputStream());
25         while (!correcto) {
26             InputStream in = ss.getInputStream();
27             BufferedReader bin = new BufferedReader(new InputStreamReader(in));
28 
29             numeroIntentado = Integer.parseInt(bin.readLine());
30 
31             if (contador == 9 && numeroIntentado != numeroAleatorio) { //Agotaronse os intentos
32                 sonuc = 4;
33 
34                 PrintWriter pout = new PrintWriter(ss.getOutputStream(), true);
35                 pout.println(sonuc);
36                 correcto = true; // Realmente non é correcto pero agotou intentos
37             }
38 
39             if (numeroIntentado == numeroAleatorio) { // Número acertado!
40                 sonuc = 1;
41 
42                 PrintWriter pout = new PrintWriter(ss.getOutputStream(), true);
43                 pout.println(sonuc);
44                 correcto = true;
45             } else if (numeroIntentado > numeroAleatorio) { // O número é menor
46                 sonuc = 3;
47                 contador++;
48                 PrintWriter pout = new PrintWriter(ss.getOutputStream(), true);
49                 pout.println(sonuc);
50             } else if (numeroIntentado < numeroAleatorio) { // O número é maior
51                 sonuc = 2;
52                 contador++;
53                 PrintWriter pout = new PrintWriter(ss.getOutputStream(), true);
54                 pout.println(sonuc);
55             }
56         }
57         ss.close();
58     }
59 }

ClienteAdivinaNumero.java

 1 import java.net.Socket;
 2 import java.net.UnknownHostException;
 3 import java.util.Scanner;
 4 import java.io.*;
 5 
 6 public class ClienteAdivinaNumero {
 7 
 8     public static void main(String args[]) throws UnknownHostException, IOException {
 9         int number, sonuc;
10         boolean correcto = false;
11         Scanner sc = new Scanner(System.in);
12         Socket s = new Socket("127.0.0.1", 9999);
13         Scanner sc1 = new Scanner(s.getInputStream());
14         while (!correcto) {
15 
16             System.out.println("Introduce un número entre 1 e 100");
17             number = sc.nextInt();
18 
19             PrintWriter pout = new PrintWriter(s.getOutputStream(), true);
20             pout.println(number);
21 
22             InputStream in = s.getInputStream();
23             BufferedReader bin = new BufferedReader(new InputStreamReader(in));
24             sonuc = Integer.parseInt(bin.readLine());
25             if (sonuc == 1) {
26                 System.out.println("Gañaches!");
27                 correcto = true;
28             } else if (sonuc == 2) {
29                 System.out.println("Máis!");
30 
31             } else if (sonuc == 3) {
32                 System.out.println("Menos!");
33             }
34 
35             if (sonuc == 4) {
36                 System.out.println("Perdiches!");
37                 correcto = true; //Non é correcto... pero agotaronse intentos!
38             }
39         }
40         s.close();
41     }
42 }

Enunciado 8 - Operacións con menú

Crea unha aplicación cliente/servidor:

  • O programa cliente
    • executará un menú con varias opcións para que elixa a operación desexada
    • despois pedirá o número co que operar
    • estes datos serán enviados ó servidor que fará o cálculo preciso e devolverá ó cliente o resultado da operación escollida

Cliente:

  • Conéctase ó servidor coa IP indicada e a través do porto 7000
  • Ofrécelle ó usuario un menú cun par de opcións (calcular cadrado ou raíz cadrada, por exemplo)
  • Pídelle ó usuario que introduza unha opción e envíase ó servidor
  • Pídelle ó usuario o número co que operar e envíase ó servidor para que faga o cálculo
  • Recíbese do servidor o resultado da operación e amósase por por pantalla ó usuario
  • Executarase ata que o usuario decida terminar pulsando a opción 3
  • Entonces péchanse os fluxos creados e a conexión co servidor
  • Deben controlarse as excepcións

Servidor:

  • Crea o socket para recibir a conexión do cliente
  • Acepta a conexión do cliente
  • Recibe o tipo de operación que o cliente desexa facer
  • Recibe o número co que deberá operar e fai os cálculos precisos
  • Amosa en pantalla o que pediu o cliente
  • Envía o resultado ó cliente
  • O servidor estará escoitando ata que o cliente decida remar coa opción 3

• Se o cliente decide finalizar aa sesión, pecha os fluxos e conexións

  • Deben controlarse as excepcións

Solución enunciado 8

Enunciado 9 - Rocha, papel, tesoiras

Fai un xogo similar o do enunciado 7, pero neste caso en lugar de adiviñar un número, o cliente tratará de derrotar ó servidor

  • o cliente escollerá rocha, peapel ou tesoiras
  • o servidor tamén escollerá rcoha, papel ou tesoiras
  • como ben e sabido, a rocha gaña ás tesoiras, as tesoiras gañánlle ó papel, e ó papel gaña á rocha
  • en caso de empate, repítse o xogo. En caso de haber un gañador, amósase quén e o gañador pola consola

Solución enunciado 9

Enunciado 10 - Tickets do museo naval

Crea unha aplicación cliente/servidor: TCP onde

  • o cliente envía o nombe de usuario e o tipo de entrada ó museo naval. O servidor xeneraralle un ticket no que figuren os datos do usuario e o importe.

Cliente:

  • Pide ó usuario o nome completo
  • Amosa os tipos de entrada
    • Normal: 10 €
    • Nenos: 2 €
    • Carne xove: 7 €
    • Terceira idade: 6 €

Servidor: Unha vez que ten todos os datos amosará pola súa consola unha entrada:

  • VISITANTE: Eulogio Touriño
  • TIPO DE ENTRADA: Terceira idade
  • A PAGAR: 6 €

O paso de datos do cliente ó servidor farase a través dun obxecto da clase Ticket que debes definir.

Solución enunciado 10

Enunciado 11 - Envio de ficheiros

Crea un programa cliente/servidor TCP:

  • que permita o envío do contido de ficheiros ó cliente
  • o cliente conectarase ó servidor polo porto 1600
  • o cliente solicitaralle o nome dun ficheiro do servidor
    • Se o ficheiro existe, o servidor enviaralle o contido do ficheiro ó cliente e este amosarao por pantalla
    • Se o ficheiro non existe, o servidor enviaralle ó cliente unha mensaxe de erro
  • Cando o cliente amose o ficheiro finalizarase a conexión.

Solución enunciado 11

Enunciado 12 - Cliente/Servidor de eco TCP

Crea un programa cliente/servidor TCP cun cliente que recibe unha mensaxe dun servidor e lle contesta;

  • o servidor está escoitando nun determinado porto
  • o servidor acepta a conexión do cliente, recolle a súa mensaxe e lle contesta
  • as mensaxes introdúcense por teclado ata que un deles escriba FIN (entón a conversación rematará)

Solución enunciado 12

Enunciado 13 - Contador de conexións

Escribe un programa que conte o número de conexions que vai recibindo:

  • disporá dun socket stream servidor
  • cada vez que un socket cliente se conecte, este enviaralle unha mensaxe co número de clientes conectados ata aora (o primer cliente que se conecte recibirá un 1, o segundo un 2, o terceiro un 3, ...)

Solución enunciado 13

Enunciado 14 - Servidor calculadora que atende múltiples peticións

Crea un programa cliente/servidor TCP:

  • que implemente unha calculadora (suma, resta, multiplicación e división)
  • o servidor debe poder atender a múltiples clientes de xeito simultaneo

Solución enunciado 14

Enunciado 15 - Chat

Solución enunciado 15