Cómo enviar un ArrayList del cliente al servidor usando UDP?

Iniciado por novato991, 27 Mayo 2019, 15:58 PM

0 Miembros y 1 Visitante están viendo este tema.

novato991

Quiero enviar una lista de números al servidor para que este al leerlos efectúe las operaciones correspondientes y devuelva el resultado de las mismas al cliente. Luego volverá a pedir números al cliente y de nuevo le devolverá el resultado correspondiente, repitiéndose el proceso hasta que el cliente introduzca un *, entonces ahí se cerraría conexión con el servidor. Tengo que hacerlo obligatoriamente utilizando protocolo UDP.

El problema es que al mandar los números por lo visto al servidor no le llegan dichos números y no hace nada. Cuando ejecuto el programa me pide los 4 números, los introduzco y ahí es donde se queda parado, el servidor no devuelve ningún resultado. Para guardar los números he utilizado el ArrayList numeros... el problema es el proceso para empaquetar esa lista de números en bytes, mandarlo al servidor y que este lo decodifique y lea esos números, ahí por lo visto no le llega la información al servidor. Soy un novato en esto de conexiones TCP/UDP, seguro que me habré equivocado pero no sé como solucionarlo, espero podáis orientarme un poco, porque estoy más perdido que un pulpo en un garaje.

Dejo los códigos de Servidor y Cliente, a ver si podéis decirme dónde he fallado...

Código (java) [Seleccionar]

   import java.awt.List;
   import java.io.ByteArrayInputStream;
   import java.io.ObjectInputStream;
   import java.net.DatagramPacket;
   import java.net.DatagramSocket;
   import java.net.InetAddress;
   import java.util.ArrayList;
   
   public class Servidor {
   
       public static void main(String args[]) throws Exception {
               
           DatagramSocket serverSocket = new DatagramSocket(9886);
           byte[] infoRecibida = new byte[1024];
           byte[] infoEnviada = new byte[1024];
           byte[] paquete = new byte[1024];
           String cadena;
           List list;
           int n1,n2,n3,n4;
           int res;
           String num;
           String num1,num2,num3,num4;
           String x;
   
           
           while (true) {
           
               System.out.println("Esperando datagrama...");            
               infoRecibida = new byte[1024];
               DatagramPacket paqRecibido = new DatagramPacket(infoRecibida, infoRecibida.length);
               serverSocket.receive(paqRecibido);            
               

            // IP y puerto desde donde se manda mensaje

               InetAddress IPOrigen = paqRecibido.getAddress();
               int puerto = paqRecibido.getPort();
               

               //Estas dos lineas supuestamente serían para poder leer el arraylist enviado desde el cliente, aunque igual estoy equivocado

               ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(infoRecibida));
               ArrayList<Integer> numeros = (ArrayList<Integer>)inputStream.readObject();
               
               n1 = numeros.get(0);
               n2 = numeros.get(1);
               n3 = numeros.get(2);
               n4 = numeros.get(3);
               
               num1= Integer.toString(n1);
               num2= Integer.toString(n2);
               num3= Integer.toString(n3);
               num4= Integer.toString(n4);
               

               // Si alguno de los números introducidos es *
               // envío "x" al cliente para que este se cierre, posteriormente sale del bucle y se cierra también el servidor

               if (num1=="*"||num2=="*"||num3=="*"||num4=="*") {
                x = "x";
                paquete = x.getBytes();
                DatagramPacket paqueteFinal = new DatagramPacket(paquete, paquete.length, IPOrigen, puerto);
                   break;
               }
               

               //Hago las operaciones, el resultado lo paso a cadena y luego a bytes, para ser enviado al cliente

               res=(n1+n2)*n3-n4;
               num = Integer.toString(res);                      
               infoEnviada=num.getBytes();
               
               

               // ENVIO DATAGRAMA AL CLIENTE

               DatagramPacket paqEnviado = new DatagramPacket(infoEnviada, infoEnviada.length, IPOrigen, puerto);
               serverSocket.send(paqEnviado);
           
           } //Fin While
   
           
           serverSocket.close();
           System.out.println("Socket cerrado...");
   
       }
   
   }




Código (java) [Seleccionar]


   import java.io.BufferedReader;
   import java.io.ByteArrayOutputStream;
   import java.io.InputStreamReader;
   import java.io.ObjectOutputStream;
   import java.net.DatagramPacket;
   import java.net.DatagramSocket;
   import java.net.InetAddress;
   import java.util.ArrayList;
   
   public class Cliente {
   
       public static void main(String[] args) throws Exception {
           
        String cadena;    
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));                
        DatagramSocket clientSocket = new DatagramSocket();
   

        //para recibir y enviar datos

           byte[] datosEnviados = new byte[1024];
           byte[] datosRecibidos = new byte[1024];
   
         
           InetAddress IPServidor = InetAddress.getByName(...); //En el paréntesis iría el número de ip del servidor adonde quiero mandarlo
           int puerto = 6000;
   
           ArrayList<Integer> numeros = new ArrayList<>();
           
           while(true) {
           
            //Rellenamos ArrayList numeros

            for(int i=0; i<4;i++) {
           System.out.println("Introduce un mensaje: ");
           cadena = in.readLine();
           numeros.add(Integer.parseInt(cadena));    
            }
           

            //Empaquetamos ArrayList en bytes para poder enviarlo al servidor

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream outputStream = new ObjectOutputStream(out);
            outputStream.writeObject(numeros);
            byte[] listData = out.toByteArray();
           
           
           DatagramPacket envio = new DatagramPacket(listData, listData.length, IPServidor, puerto);
           clientSocket.send(envio);
           outputStream.close();
           
           
           //recibimos respuesta del servidor

           DatagramPacket recibo = new DatagramPacket(datosRecibidos, datosRecibidos.length);
           System.out.println("Esperando datagrama...");
           clientSocket.receive(recibo);
           String numero = new String(recibo.getData());

               //Si el dato que devuelve el servidor es "x", salimos del bucle y se cierra el cliente      
           if (numero.equals("x")) {
               break;          
           }        
           System.out.println("\t Datos: " + numero);      
           
           } //Fin While
           
           clientSocket.close(); //Cerramos cliente
       }
   
   }





Mod: Obligatorio el uso de etiquetas GeSHi para sources.

rub'n

#1
Hay tienes para que te aburras más de lo que estás.

Tienes malas prácticas, debes mejorarlas dog, aqui algunos tips a repasar

* Método main hyper recargado, separa la lógica del negocio para que tu api sea mas usable, mi ejemplo no es el mejor, pero esa es la idea.
* Falta del uso de try-with resources
* Usa java.util.List en ves de java.awt.List
* Usa un buen IDE, o aprende a usar bien el que tienes
* Usa un analizador de código estático como sonar o findbugs
* Por cada datagrama UDP enviado desde el server, en el cliente debes crear también la cantidad igual o sea,
new DatagramPacket()
* Wrappers, las clases de bajo nivel con las de alto nivel, ByteArray de Input/OutputStream, envuélvelos/wrapper con otras clases de alto nivel, mas o menos como hiciste con ObjectInputStream, pero hazlo mas legible.





* Pues hace lo que se pide, introduce 4 número para llenar la java.util.List no la q estabas usando, error primordial.
* Son procesados en el servidor UDP para ser luego retornados
* Si en esos números introducidos está un asterisco, lo usamos como flag, para salirnos del while del cliente, e invocar a
.close(), otra cosa es que la conexión UDP se cierra distinto a la tcp, al invocar a .close() este libera el puerto usado por ese socket, pero segun lo que veo, el puerto queda si escaneamos en windows con un netstat -aon, pero sin poderse usar, con UDP, no hay garantía de la entrega de datagramas que viajan por la red, esto último se parece a la frase en mi blog, pero esta es más *****  >:D


Usa GeSHi


Código (java) [Seleccionar]

import java.util.logging.Logger;

/**
* interface con Logger
*/
public interface UDPLogger {

   default void info(final String info) {
       Logger.getLogger("UdpLogger").info(info);
   }

   default void error(final String error) {
       Logger.getLogger("UdpLogger").warning(error);
   }
}


Server PoC

Código (java) [Seleccionar]
package com.foro;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
* @author rub´n
*/
public class ServerUDPListaProcesarPoC implements UDPLogger {

   private static final int PUERTO = 13;
   private ExecutorService es = Executors.newFixedThreadPool(50);

   /**
    * Unico constructor de esta clase
    */
   public ServerUDPListaProcesarPoC() {
       /*
        * Async
        */
       CompletableFuture.runAsync(this::initServer, es);
   }

   /**
    * Equivalen a 2 datagramas aka UDP packets
    *
    * dos metodos que ejecutara el server al cliente
    * la hora y la lista de numeros procesadas con la formula (n1 + n2 ) * n3 - n4;
    *  - enviarHoraAlCliente(datagramSocket, request);
    *  - enviarListaProcesadaAlCliente(datagramSocket, request);
    *
    */
   private void initServer() {

       try (final DatagramSocket datagramSocket = new DatagramSocket(PUERTO)) {
           info("Servidor UDP iniciado correctamente por el puerto: " + PUERTO);
           while (Boolean.TRUE) {
               try {
                   final byte[] byteBuffer = new byte[1024];
                   final DatagramPacket request = new DatagramPacket(byteBuffer, byteBuffer.length);
                   datagramSocket.receive(request);

                   enviarHoraAlCliente(datagramSocket, request);
                   enviarListaProcesadaAlCliente(datagramSocket, request);

               } catch (IOException | RuntimeException e) {
                   error(e.toString());
               }
           }
       } catch (IOException e) {
           error(e.toString());
       }
   }

   /**
    * enviar hora al cliente
    *
    * @param request
    * @param socket
    */
   private void enviarHoraAlCliente(final DatagramSocket socket, final DatagramPacket request) {
       /*
        * Metodo que obtiene la hora como ejemplo
        * solo ejemplo :D
        */
       final byte[] data = getHora().getBytes();
       /*
        * Este datagrama se le enviara como respuesta al cliente
        */
       final DatagramPacket response = new DatagramPacket(data, data.length, request.getAddress(), request.getPort());
       try {
           /*
            * Enviando datos al cliente
            */
           socket.send(response);
       } catch (IOException e) {
           error(e.toString());
       }

       /*
        * Imprimimos el datagrama UDP originado, junto con la direccion ip del cliente mas el puerto
        */
       info(new String(data) + " - " + request.getAddress() + ":" + request.getPort());
   }

   /**
    * @param socket
    * @param request
    */
   private void enviarListaProcesadaAlCliente(final DatagramSocket socket, final DatagramPacket request) {
       /*
        * Request
        */
       final byte[] data = procesarLista(request);
       final DatagramPacket response = new DatagramPacket(data, data.length, request.getAddress(), request.getPort());

       try {
           /*
            * Enviando datos al cliente
            */
           socket.send(response);
       } catch (IOException e) {
           error(e.toString());
       }
       /*
        * Imprimimos el datagrama UDP originado, junto con la direccion ip del cliente mas el puerto
        */
       info(new String(data) + " - " + request.getAddress() + ":" + request.getPort());
   }

   /**
    * (n1+n2)*n3-n4
    * procesar lista aqui, o sea, leeremos esos bytes de la siguiente manera
    *
    */
   private byte[] procesarLista(final DatagramPacket listaEnFormaDeBytes) {
       /*
        * Wrappers, y escritos con Try-With resources
        * constructor usado ByteArrayInputStream(byte buf[], int offset, int length)
        * para evitar que el datagrama contenga algun valor mother fucker
        */
       try (final ByteArrayInputStream byteArray = new ByteArrayInputStream(listaEnFormaDeBytes.getData(), listaEnFormaDeBytes.getOffset(), listaEnFormaDeBytes.getLength());
            final InputStreamReader inputStreamReader = new InputStreamReader(byteArray);
            final BufferedReader br = new BufferedReader(inputStreamReader)) {

           String line;
           String asterisco = "";
           final StringBuilder sb = new StringBuilder();
           while (Objects.nonNull(line = br.readLine())) {
               if (line.contains("*")) {
                   asterisco = line.trim();
                   break;
               }
               sb.append(line);
           }

           if (asterisco.trim().contains("*")) {//si hay asterisco, obtenemos sus bytes
               return "*".getBytes();
           } else {
               final String sLine = sb.toString().trim();
               final int n1 = Integer.parseInt(sLine.split("-")[0]);
               final int n2 = Integer.parseInt(sLine.split("-")[1]);
               final int n3 = Integer.parseInt(sLine.split("-")[2]);
               final int n4 = Integer.parseInt(sLine.split("-")[3]);

               final int iResultado = (n1 + n2) * n3 - n4;
               return ("-> Resultado (n1 + n2 ) * n3 - n4: " + iResultado).getBytes();
           }
       } catch (IOException ex) {
           error(ex.toString());
       }
       return new byte[0];//cero en caso de algún error
   }

   /**
    *
    * @return String con la hora formateada
    */
   private String getHora() {
       return DateTimeFormatter.ofPattern("eeee, d  'de' MMMM 'de' uuuu hh:mm:ssS a")
               .withLocale(Locale.getDefault())
               .withZone(ZoneId.systemDefault())
               .format(Instant.now());
   }

   public static void main(String... queVivaLaPachamama) {
       new ServerUDPListaProcesarPoC();
   }

}


Cliente PoC

Código (java) [Seleccionar]
package com.foro;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.swing.JOptionPane;


/**
* @author rub´n
*/
public class ClientUDPListaProcesarPoC implements UDPLogger {

   private static final int PUERTO = 13;
   private final byte[] byteBuffer = new byte[1024]; //1k
   private static final Scanner LEER = new Scanner(System.in);
   private Boolean isFinished = Boolean.FALSE;

   /*
    * Unico constructor de esta clase
    */
   public ClientUDPListaProcesarPoC() {
       initClientUDP();
   }

   private Boolean isFinished() {
       return isFinished;
   }

   private void initClientUDP() {

       while (!isFinished()) {
           try (final DatagramSocket socket = new DatagramSocket(0)) {// Cero, produce un puerto aleatorio

               socket.setSoTimeout(5000); //5 segundos de tiempo de espera maximo
               final InetAddress localHost = InetAddress.getLocalHost();//conexion con localhost
               final DatagramPacket request = new DatagramPacket(byteBuffer, byteBuffer.length, localHost, PUERTO);

               final byte[] listaParaProcesarEnServidor = getListaParaProcesarEnServidor();


               request.setData(listaParaProcesarEnServidor);
               /*
                * enviando los datos al servidor
                */
               socket.send(request);

               /*
                * leyendo respuesta del server
                */
               respuestasDelServidor(socket);

           } catch (IOException e) {
               error(e.toString());
           }
       }


   }

   /**
    * @param socket
    */
   private void respuestasDelServidor(final DatagramSocket socket) {
       /*
        * Aqui craremos 2 datagramas uno para la fecha y otro para la lista
        * el primer datagrama equivale a la fecha, solo de ejemplo
        */
       try {
           final DatagramPacket response = new DatagramPacket(byteBuffer, byteBuffer.length);
           socket.receive(response);
           final String dataGrama1 = new String(response.getData(), response.getOffset(), response.getLength(), StandardCharsets.UTF_8);
           info(dataGrama1);

           /*
            * En este datagrama si viene la lista con el resultado
            */
           final DatagramPacket response2 = new DatagramPacket(byteBuffer, byteBuffer.length);
           socket.receive(response2);
           final String dataGrama2 = new String(response2.getData(), response2.getOffset(), response2.getLength(), StandardCharsets.UTF_8);

           if (dataGrama2.equals("*")) {
               info("Conexion cerrada");
               JOptionPane.showMessageDialog(null, "Conexion cerrada.");
               socket.close();
               isFinished = Boolean.TRUE; //flag para salir del while de este cliente
           }
           info(dataGrama2);
       } catch (IOException e) {
           error(e.toString());
       }
   }

   /**
    * @return byte[] que seran enviados al Servidor para procesar
    */
   private byte[] getListaParaProcesarEnServidor() {

    final List<String> listaNumeros = new CopyOnWriteArrayList<>();
       info("Introduce 4 numeros, o (*) para cerrar conexión");
       for (int f = 0; f < 4; f++) {
           info("Introduce numero " + (f + 1));
           final String value = LEER.next().trim();
           if (value.contains("*")) {//si contiene es *, salir del for
               listaNumeros.add(value);
               break;
           }
           listaNumeros.add(value);
       }

       /*
        * String retornado con metodo join mas concatenacion de - entre sus numeros
        * para usarlos como flag en el server desde la línea 153
        * por ultimo invocamos a getBytes() gracias al paso anterior
        */
       return String.join("-", listaNumeros).getBytes();
   }

   public static void main(String... MaduroMotherFucker) {
       new ClientUDPListaProcesarPoC();
   }

}



Versión Server PoC con builder básico.

Código (java) [Seleccionar]

package com.foro;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static java.util.Objects.nonNull;

/**
* @author rub´n
*
*
   ServerUDPListaProcesarPoC.newBuilder()
       .conPuertoMasBufferSize(13, 1024)
       .conFlagParaCerrarPuerto("*")
       .conNumeroDeHilos(50)
       .crearSocketUdp()
       .respuesta()
       .build();

*/
public class ServerUDPListaProcesarPoC implements UDPLogger {

   private int puerto;
   private int bufferSize;
   private int numeroHilos;
   private DatagramSocket socket;
   private DatagramPacket datagramPacket;
   private String flagParaCerrarPuerto;
   private ExecutorService es;

   /**
    * Unico constructor de esta clase
    */
   private ServerUDPListaProcesarPoC() {
   }

   public static ServerUDPListaProcesarPoC newBuilder() {
       return new ServerUDPListaProcesarPoC();
   }

   public ServerUDPListaProcesarPoC conNumeroDeHilos(int numeroDeHilos) {
       es = Executors.newFixedThreadPool(numeroDeHilos);
       return this;
   }

   public ServerUDPListaProcesarPoC conPuertoMasBufferSize(final int puerto, final int bufferSize) {
       this.bufferSize = bufferSize;
       this.puerto = puerto;
       return this;
   }

   public ServerUDPListaProcesarPoC conFlagParaCerrarPuerto(final String flag) {
       this.flagParaCerrarPuerto = flag;
       return this;
   }

   public ServerUDPListaProcesarPoC build() {
       return new ServerUDPListaProcesarPoC();
   }

   /**
    * Equivalen a 2 datagramas aka UDP packets
    * <p>
    * dos metodos que ejecutara el server al cliente
    * la hora y la lista de numeros procesadas con la formula (n1 + n2 ) * n3 - n4;
    * - enviarHoraAlCliente(datagramSocket, request);
    * - enviarListaProcesadaAlCliente(datagramSocket, request);
    */
   private ServerUDPListaProcesarPoC crearSocketUdp() {
           try {
               this.socket = new DatagramSocket(puerto);
               info("Servidor UDP iniciado correctamente por el puerto: " + puerto);

           } catch (IOException e) {
               error(e.toString());
           }
       return this;
   }

   public ServerUDPListaProcesarPoC respuesta() {
      CompletableFuture.runAsync(() -> {
           while (Boolean.TRUE) {
               final byte[] byteBuffer = new byte[bufferSize];
               this.datagramPacket = new DatagramPacket(byteBuffer, byteBuffer.length);
               try {
                   this.socket.receive(datagramPacket);
               } catch (IOException e) {
                   e.printStackTrace();
               }
               enviarHoraAlCliente();
               enviarListaProcesadaAlCliente();
           }
       },es);
       return this;
   }

   /**
    * enviar hora al cliente
    *
    */
   private ServerUDPListaProcesarPoC enviarHoraAlCliente() {
       /*
        * Metodo que obtiene la hora como ejemplo
        * solo ejemplo :D
        */
       final byte[] data = getHora().getBytes();
       /*
        * Este datagrama se le enviara como crearSocketUdp al cliente
        */
       final DatagramPacket response = new DatagramPacket(data, data.length, this.datagramPacket.getAddress(), this.datagramPacket.getPort());
       try {
           /*
            * Enviando datos al cliente
            */
           this.socket.send(response);
       } catch (IOException e) {
           error(e.toString());
       }

       /*
        * Imprimimos el datagrama UDP originado, junto con la direccion ip del cliente mas el puerto
        */
       info(new String(data) + " - " + datagramPacket.getAddress() + ":" + datagramPacket.getPort());
       return this;
   }

   /**
    */
   private ServerUDPListaProcesarPoC enviarListaProcesadaAlCliente() {
       /*
        * Request
        */
       final byte[] data = procesarLista(datagramPacket);
       final DatagramPacket respuestaAlCliente = new DatagramPacket(data, data.length, datagramPacket.getAddress(), datagramPacket.getPort());

       try {
           /*
            * Enviando datos al cliente
            */
           this.socket.send(respuestaAlCliente);
       } catch (IOException e) {
           error(e.toString());
       }
       /*
        * Imprimimos el datagrama UDP originado, junto con la direccion ip del cliente mas el puerto
        */
       info(new String(data) + " - " + datagramPacket.getAddress() + ":" + datagramPacket.getPort());
       return this;
   }

   /**
    * (n1+n2)*n3-n4
    * procesar lista aqui, o sea, leeremos esos bytes de la siguiente manera
    */
   private byte[] procesarLista(final DatagramPacket listaEnFormaDeBytes) {
       /*
        * Wrappers, y escritos con Try-With resources
        * constructor usado ByteArrayInputStream(byte buf[], int offset, int length)
        * para evitar que el datagrama contenga algun valor mother fucker
        */
       try (final ByteArrayInputStream byteArray = new ByteArrayInputStream(listaEnFormaDeBytes.getData(),
               listaEnFormaDeBytes.getOffset(), listaEnFormaDeBytes.getLength());
            final InputStreamReader inputStreamReader = new InputStreamReader(byteArray);
            final BufferedReader br = new BufferedReader(inputStreamReader)) {

           String line;
           String asterisco = "";
           final StringBuilder sb = new StringBuilder();
           while (nonNull(line = br.readLine())) {
               if (line.contains(flagParaCerrarPuerto)) {
                   asterisco = line.trim();
                   break;
               }
               sb.append(line);
           }

           if (asterisco.trim().contains(flagParaCerrarPuerto)) {//si hay asterisco, obtenemos sus bytes
               return flagParaCerrarPuerto.getBytes();
           } else {
               final String sLine = sb.toString().trim();
               final int n1 = Integer.parseInt(sLine.split("-")[0]);
               final int n2 = Integer.parseInt(sLine.split("-")[1]);
               final int n3 = Integer.parseInt(sLine.split("-")[2]);
               final int n4 = Integer.parseInt(sLine.split("-")[3]);

               final int iResultado = (n1 + n2) * n3 - n4;
               return ("-> Resultado (n1 + n2 ) * n3 - n4: " + iResultado).getBytes();
           }
       } catch (IOException ex) {
           error(ex.toString());
       }
       return new byte[0];//cero en caso de algún error
   }

   public static void main(String... queVivaLaPachamama) {
       ServerUDPListaProcesarPoC.newBuilder()
               .conPuertoMasBufferSize(13, 1024)
               .conFlagParaCerrarPuerto("*")
               .conNumeroDeHilos(50)
               .crearSocketUdp()
               .respuesta()
               .build();
   }

}



rubn0x52.com KNOWLEDGE  SHOULD BE FREE!!!
If you don't have time to read, you don't have the time (or the tools) to write, Simple as that. Stephen

Serapis

Citar
Soy un novato en esto de conexiones TCP/UDP, seguro que me habré equivocado pero no sé como solucionarlo
...
espero podáis orientarme un poco, porque estoy más perdido que un pulpo en un garaje.
...
Quiero enviar una lista de números al servidor para que este al leerlos efectúe las operaciones correspondientes y......... devuelva el resultado de las mismas al cliente. Luego volverá a pedir números al cliente y de nuevo le devolverá el resultado correspondiente, repitiéndose el proceso hasta que el cliente introduzca un *, entonces ahí se cerraría conexión con el servidor. Tengo que hacerlo obligatoriamente utilizando protocolo UDP.

Tú dí lo que quieras, pero esto apesta a virus que tira para atrás... incluso ese descargo de intenciones del 'pulpo perdido en el garage', hace que apeste todavía más...

El protocolo UDP, no se inventó para envío masivo de datos, el que se empeña en ello, no puede tener otra finalidad que camuflar la comunicación de un troyano...

Es lo mismo que si un tipo dice que quiere enviar 1000 toneladas de piezas metálicas pero que lo haga un ciclista pieza a pieza... un volumen grande se envía en camiones, trenes, etc... es más rápido y más barato. ...un transportista deja firma en albaranes, partidas de transporte, horarios, etc... que pueden rastrearse. Hacerlo a 'pequeña' escala solo puede tener malas intenciones, a base de no llamar la atención. Así que si alguien quiere mover 1000 toneladas de piezas en bicicleta, lo siento pero pensar que se trata de un terrorista pasa a ser la primera (y probablemente la única) sospecha.