Diferencia entre revisiones de «Solucións as prácticas con Sockets TCP»
Línea 513: | Línea 513: | ||
} | } | ||
} | } | ||
+ | |||
+ | </syntaxhighlight> | ||
'''ClienteAdivinaNumero.java''' | '''ClienteAdivinaNumero.java''' |
Revisión del 15:28 25 nov 2021
Sumario
- 1 Enunciado 1 - Envío de mensaxe
- 2 Enunciado 2 - Duplicando número
- 3 Enunciado 3 - Convertindo a maiúsculas
- 4 Enunciado 4 - Escaneando portos
- 5 Enunciado 5 - Conectando con servidor e porto indicado
- 6 Enunciado 6 - Factorial ou Fibonacci
- 7 Enunciado 8 - Operacións con menú
- 8 Enunciado 9 - Rocha, papel, tesoiras
- 9 Enunciado 10 - Tickets do museo naval
- 10 Enunciado 11 - Envio de ficheiros
- 11 Enunciado 12 - Cliente/Servidor de eco TCP
- 12 Enunciado 13 - Contador de conexións
- 13 Enunciado 14 - Servidor calculadora que atende múltiples peticións
- 14 Enunciado 15 - Chat
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
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