Real Time Java Android Stream [Resuelto]

Para dar las gracias debes entrar o registrarte en el foro

Recién llegado
Recién llegado
Mensajes: 2 Agradecido: 2
19 Oct 2013, 08:40# 1

Muy buenas:
Estoy tratando de hacer un lazo de audio mediante una conexión Servidor (Java) - Cliente (Android) en tiempo real. El Servidor (ordenador/Java) manda al cliente datos que el Cliente (dispositivo móvil/Android) retorna sin más y el Servidor vuelve a leer.

Os pongo un trozo del código para aclarar:
- Servidor:

Código: Seleccionar todo
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Esta clase implementa un servidor TCP.


 */
public class GTCPServer {

   public static final int SERVER_PORT = 4444; // Nº de puerto
   private boolean running = true; // Booleano para controlar el flujo
   
   private ServerSocket serverSocket; // Socket Servidor
   
   // Streams de entrada y salida:
   private DataInputStream dis;
   private DataOutputStream dos;
   
   // Buffer:
   private byte[] bytes;
   private static final int BUFFER_SIZE = 512 * 4; // Tamaño

   /**
    * Constructor. Inicia el Servidor.
    */
   public GTCPServer() {
      bytes = new byte[BUFFER_SIZE]; // Instanciamos el buffer
      
      // Le metemos valores para probar:
      bytes[0] = 3;
      bytes[BUFFER_SIZE - 1] = 7;
      
      try {
         // Creamos el Socket de Servidor y esperamos peticiones que vengan a través de la red.
         serverSocket = new ServerSocket(SERVER_PORT);
         System.out.println("Conectando...");

         // Mediante el método accept() nos mantenemos a la espera de una conexión.
         // En el momento se produce esta, creamos el Socket de Cliente:
         Socket client = serverSocket.accept();
         System.out.println("Recibiendo...");

         try {
            // Instanciamos los flujos de entrada y salida:
             dis = new DataInputStream(client.getInputStream());
             dos = new DataOutputStream(client.getOutputStream());
         } catch (Exception e) {
            System.out.println("Error.");
            e.printStackTrace();
         }
      } catch (Exception e) {
         System.out.println("Error.");
         e.printStackTrace();
      }
   } // GTCPServer()
   
   /**
    * Envía (escribe) un buffer de bytes por TCP.
    * @param buffer - La memoria intermedia donde se almacenan los datos a enviar.
    * @param offset - Posición del buffer desde donde empieza a enviar.
    * @param count - Número de bytes a escribir.
    */
   public void write(byte[] buffer, int offset, int count) {
      try {
         dos.write(buffer, offset, count); // Escribimos por TCP
      } catch (IOException e) {
         e.printStackTrace();
      }
   } // write()

} // GTCPServer



- Cliente:
Código: Seleccionar todo
import android.util.Log;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

import com.appacoustic.java.g.G;

public class GTCPClient_A {

   public static final String SERVER_IP = "192.168.1.101"; // IP del Servidor (PC)
   public static final int SERVER_PORT = 4444; // Nº de puerto
   private boolean running = true; // Booleano para controlar el flujo
   
   // Streams de entrada y salida:
   private DataInputStream dis;
   private DataOutputStream dos;
   
   // Buffer:
   private byte[] bytes;
   private static final int BUFFER_SIZE = 512 * 4; // Tamaño
   
   /**
    * Constructor.
    */
   public GTCPClient_A() {
      bytes = new byte[BUFFER_SIZE]; // Instanciamos el buffer
   } // GTCPClient_A()

   /**
    * Ejecución del hilo. No está sobreescrito el método porque usamos una subclase (connectTask) que extiende de AsyncTask.
    */
   public void run() {
      try {
         // Obtenemos el InetAddress a partir de la dirección IP (IPv4 del ordenador) del Servidor
         InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
         Log.e("GTCPClient_A", "Conectando...");

         // Creamos un socket para conectarnos con el Servidor:
         Socket socket = new Socket(serverAddr, SERVER_PORT);

         try {
            // Instanciamos los flujos de entrada y salida:
            dis = new DataInputStream(socket.getInputStream());
            dos = new DataOutputStream(socket.getOutputStream());

            int lap = 0; // Para llevar la cuenta de las vueltas
            
            // Este while sirve para que el Cliente esté escuchando los mensajes enviados por el Servidor:
            while (running) {
               dis.read(bytes); // Leemos por TCP
               System.out.println("IN_ini_["+lap+"]: "+bytes[0]);
                System.out.println("IN_fin_["+lap+"]: "+bytes[BUFFER_SIZE - 1]);
               
                G.toc = System.currentTimeMillis();
               G.ticToc();
               G.tic = G.toc;
               
               dos.write(bytes); // Escribimos por TCP
               System.out.println("OUT_ini_["+lap+"]: "+bytes[0]);
               System.out.println("OUT_fin_["+lap+"]: "+bytes[BUFFER_SIZE - 1]);
               
               lap++;
            }
         } catch (Exception e) {
            Log.e("GTCP", "SERVIDOR: Error", e);
         } finally {
            // El Socket debe de ser cerrado. No es posible hacer una reconexión a este Socket.
            // Después de esto se debe de realizar una nueva instancia de Socket para poder comunicarse con el Servidor.
            socket.close();
         }
      } catch (Exception e) {
         Log.e("GTCP", "CLIENTE: Error", e);
      }
   } // run()
   
} // GTCPClient_A

He programado esto mediante Bluetooth y TCP sin resultados óptimos. Mi sorpresa ha sido que al probar a implementar el Cliente en Java en vez de Android, sí que funciona (el código es prácticamente idéntico). De hecho hablo por el micrófono (he programado los drivers ASIO con JASIOHost), desde el ordenador donde tengo el Servidor, los datos viajan por TCP hasta otro ordenador dentro de la misma WIFI, retornan y se escucha perfectamente en tiempo real por altavoces en el ordenador del Servidor.

O sea, que al parecer el problema reside en algo de Android. Pero yo lo que pretendo es usar un smartphone o una tablet como Cliente.

Llevo meses tratando de encontrar una solución sin éxito... ¿Alguien me puede ayudar?
Última edición por GabrielMoreno el 23 Oct 2013, 17:01, editado 1 vez en total
Gracias  
Etiquetado en:
Recién llegado
Recién llegado
Mensajes: 2 Agradecido: 2
23 Oct 2013, 17:01# 2

La solución era hacerlo mediante UDP. Es más apropiada para aplicaciones en tiempo real que TCP, ya que no precisa de confirmación en el receptor al enviar datos por la red y eso le confiere mayor velocidad. Además, si se pierde algún paquete por el camino, no es tan relevante como para otro tipo de sistemas.

Gracias  
2 personas han dado las gracias: mcgyvermacconian

Publicidad

Patrocinadores

Publicidad