Programación y Desarrollo para Android Subforo exclusivo para temas de programación de software para PDAs y desarrollo de aplicaciones, interfaces, etc bajo Android

Respuesta
 
Herramientas
  #1  
Viejo 27/12/13, 12:22:29
Array

[xs_avatar]
manolazo manolazo no está en línea
Miembro del foro
 
Fecha de registro: jun 2012
Localización: Madrid
Mensajes: 219
Modelo de smartphone: Samsung Galaxy S7 edge
Tu operador: Pepephone
Error sockets entre server y cliente en android.

Buenas.

Intento establecer conexion entre un servidor creado en java Netbeans, en lineas generales en la clase del servidor:

Código:
        ServerSocket server = new ServerSocket(puerto); //puerto = 30922;
	 while (true){
            Socket client = server.accept();
            System.out.println("Aceptado desde :"+client.getInetAddress());
            ChatHandler c = new ChatHandler(client);
            c.start();
        }
donde en la clase ChatHandler para no extendernos el constructor seria:

Código:
 public ChatHandler (Socket s) throws IOException{
       		 this.s=s;
        	in = new DataInputStream(new BufferedInputStream(s.getInputStream()));
        	out = new DataOutputStream ( new BufferedOutputStream(s.getOutputStream()));
    	}
Por parte del ciente android a grandes rasgos en onCreate:

Código:
     String ip = "192.168.1.2";
             int puerto = 30922;
             Log.v(this.getClass().getClass().getCanonicalName(), "Socket " + ip + " " + puerto);
             try {
                     sk = new Socket(ip, puerto);                   
                     Log.v(getClass().getCanonicalName(), "Se ha iniciado conexion...");
                     Log("Conexion con servidor: "+ip+" Puerto: "+puerto);
                     entrada = new DataInputStream(new BufferedInputStream(sk.getInputStream()));
                     salida = new DataOutputStream(new BufferedOutputStream(sk.getOutputStream()));

             } catch (UnknownHostException e) {
                     e.printStackTrace();
                     salidaTxt.append(e.getMessage());
             } catch (IOException e) {
                     e.printStackTrace();
                     salidaTxt.append(e.getMessage());
             }

Pero me salta la exception con error de conexion. Supongo que sera por las ips , pero no logro dar con ello.

Lo estoy haciendo con el avd de eclipse y supongo que la ip que tendre que poner "192.168.1.2" es la ip donde esta el pc?

ando un poco perdido.

Un saludo.
Responder Con Cita


  #2  
Viejo 28/12/13, 09:32:44
Array

[xs_avatar]
jtsamper jtsamper no está en línea
Miembro del foro
 
Fecha de registro: abr 2013
Localización: Madrid
Mensajes: 149
Modelo de smartphone: Xperia Arc, Nexus 5
Tu operador: Movistar
Si, deberas meterle la ip de tu pc y el puerto por el que se comunican. Y fijate qe este corriendo el servidor antes de iniciar el cliente. Tambien comprueba que el avd te conecta a internet.

Pero creo qe el fallo esta en el servidoe porque no habre correctamente los sockets. Has comprobado si te salta errores en el servidor???
__________________
Controlador de Medicamentos 1.5 (https://play.google.com/store/apps/d...mentcontrolled)
Legislación Basica Española 1.1 (https://play.google.com/store/apps/d...islacionbasica)
Responder Con Cita
  #3  
Viejo 28/12/13, 12:52:28
Array

[xs_avatar]
manolazo manolazo no está en línea
Miembro del foro
 
Fecha de registro: jun 2012
Localización: Madrid
Mensajes: 219
Modelo de smartphone: Samsung Galaxy S7 edge
Tu operador: Pepephone
Hola.

El avd lo tengo conectado a internet porque he probado a abrir navegador en el avd y funciona.
El puerto esta abierto y la ip es la del pc.
El servidor esta corriendo lo abro desde netbeans pero no se si abre correctamente los sockets ya que el error salta cuando ejecuto la aplicacion cliente desde eclipse.

trazas:

Código:
12-28 11:45:53.281: E/AndroidRuntime(840): FATAL EXCEPTION: main
12-28 11:45:53.281: E/AndroidRuntime(840): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.socketclientprueba/com.example.socketclientprueba.SocketCliente}: android.os.NetworkOnMainThreadException
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.app.ActivityThread.access$600(ActivityThread.java:141)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.os.Handler.dispatchMessage(Handler.java:99)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.os.Looper.loop(Looper.java:137)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.app.ActivityThread.main(ActivityThread.java:5041)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at java.lang.reflect.Method.invokeNative(Native Method)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at java.lang.reflect.Method.invoke(Method.java:511)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at dalvik.system.NativeStart.main(Native Method)
12-28 11:45:53.281: E/AndroidRuntime(840): Caused by: android.os.NetworkOnMainThreadException
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at libcore.io.IoBridge.connect(IoBridge.java:112)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at java.net.Socket.startupSocket(Socket.java:566)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at java.net.Socket.tryAllAddresses(Socket.java:127)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at java.net.Socket.<init>(Socket.java:177)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at java.net.Socket.<init>(Socket.java:149)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at com.example.socketclientprueba.SocketCliente.onCreate(SocketCliente.java:72)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.app.Activity.performCreate(Activity.java:5104)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
12-28 11:45:53.281: E/AndroidRuntime(840): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
12-28 11:45:53.281: E/AndroidRuntime(840): 	... 11 more
Responder Con Cita
  #4  
Viejo 28/12/13, 13:25:19
Array

[xs_avatar]
jtsamper jtsamper no está en línea
Miembro del foro
 
Fecha de registro: abr 2013
Localización: Madrid
Mensajes: 149
Modelo de smartphone: Xperia Arc, Nexus 5
Tu operador: Movistar
Mmmm tienes el permiso de internet en la aplicacion? Supongo que si.

Mete el hilo del cliente en un servicio, de esta forma no te dara problemas, y utilizar el IBinder para comunicarlo con la actividad.

Espero que sirva de ayuda.
__________________
Controlador de Medicamentos 1.5 (https://play.google.com/store/apps/d...mentcontrolled)
Legislación Basica Española 1.1 (https://play.google.com/store/apps/d...islacionbasica)
Responder Con Cita
  #5  
Viejo 28/12/13, 13:31:03
Array

[xs_avatar]
Arasthel Arasthel no está en línea
Cocinero veterano
· Votos compra/venta: (1)
 
Fecha de registro: jun 2009
Localización: Almería
Mensajes: 1,946
Modelo de smartphone: Nexus 5
Tu operador: Amena
Trabajo asíncrono con red -> hilo aparte. Ponlo en un Thread o en el doInBackground de un AsyncTask y no reventará.

@jtsamper: meter el código en un service sólo para eso es un poco matar moscas a cañonazos, a no ser que tenga que estar funcionando incluso si la app no o que tenga que compartirse en varias activities. Además, si no recuerdo mal, el código de un service sigue ejecutándose en el hilo principal (al menos si está en un proceso aparte).

Un saludo.

Última edición por Arasthel Día 28/12/13 a las 13:35:49.
Responder Con Cita
Gracias de parte de:
  #6  
Viejo 28/12/13, 15:22:45
Array

[xs_avatar]
manolazo manolazo no está en línea
Miembro del foro
 
Fecha de registro: jun 2012
Localización: Madrid
Mensajes: 219
Modelo de smartphone: Samsung Galaxy S7 edge
Tu operador: Pepephone
Buenas.

Si, tengo puesto el permiso de internet en el Manifest:
<uses-permission android:name="android.permission.INTERNET"/>

Y aunque no lo haya puesto en el código, tambien esta creado un hilo aparte para recoger mensaje desde DataInputStream

El codigo del OnCreate del cliente:

Código:
 @Override
     public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_socket_cliente);
             texto = (EditText) findViewById(R.id.EditText01);
             salidaTxt = (TextView) findViewById(R.id.TextView01);
             contador = (TextView) findViewById(R.id.textView1);            

             btnEnviar = (Button) findViewById(R.id.button1);
             btnEnviar.setOnClickListener(new View.OnClickListener() {

                     public void onClick(View v) {
                             Log.v(getClass().getCanonicalName(), "Iniciando Socket...");
                             Log("Enviando... " + texto.getText().toString() + "\n");
                             ejecutaClienteSocket();
                     }
             });

             String ip = "192.168.1.2";
             int puerto = 30922;
             Log.v(this.getClass().getClass().getCanonicalName(), "Socket " + ip + " " + puerto);
             try {
                     sk = new Socket(ip, puerto);                   
                     Log.v(getClass().getCanonicalName(), "Se ha iniciado conexion...");
                     Log("Conexion con servidor: "+ip+" Puerto: "+puerto);
                     entrada = new DataInputStream(new BufferedInputStream(sk.getInputStream()));
                     salida = new DataOutputStream(new BufferedOutputStream(sk.getOutputStream()));

             } catch (UnknownHostException e) {
                     e.printStackTrace();
                     salidaTxt.append(e.getMessage());
             } catch (IOException e) {
                     e.printStackTrace();
                     salidaTxt.append(e.getMessage());
             }

            
             final Handler myHandler = new Handler();
             
             (new Thread(new Runnable() {
                 public void run() {
                      while (true) {
                         String recibe;
                         try {
                            recibe = getEntrada().readUTF();
                            if (recibe != null) {
                                  SocketCliente.this.setMsg(recibe);
                                  Log.v(getClass().getCanonicalName(), "Recibiendo datos.." + recibe);
                            }

                         }catch (IOException e) {                                            
                                  e.printStackTrace();
                         }
                         myHandler.post(new Runnable() {
                             public void run() {
                                 actualizarMensajes();
                             }
                         });
                     }
               }
             })).start();
            
            
             Log.v(getClass().getCanonicalName(), "Terminando de iniciar componentes");
     }
El handler es para mostrar en un textview el mensaje recibido.

Da la impresion de que es un error de conexion de sockets , no?
Responder Con Cita
  #7  
Viejo 28/12/13, 16:23:05
Array

[xs_avatar]
Arasthel Arasthel no está en línea
Cocinero veterano
· Votos compra/venta: (1)
 
Fecha de registro: jun 2009
Localización: Almería
Mensajes: 1,946
Modelo de smartphone: Nexus 5
Tu operador: Amena
La creación del socket la haces fuera del hilo, y tiene toda la pinta de ser eso lo que da fallo (al menos según el logcat). ¿Qué línea es la 72 en tu código?

 Cita:
12-28 11:45:53.281: E/AndroidRuntime(840): at com.example.socketclientprueba.SocketCliente.onCre ate(SocketCliente.java:72)
Un saludo.
Responder Con Cita
  #8  
Viejo 28/12/13, 16:44:22
Array

[xs_avatar]
kriogeN kriogeN no está en línea
Colaborador/a
· Votos compra/venta: (1)
 
Fecha de registro: oct 2010
Localización: Murcia
Mensajes: 4,637
Modelo de smartphone: Samsung Galaxy S7 Edge SM-G935F
Tu operador: Vodafone
Como dice Arasthel, la creación de la conexión la haces en el hilo principal, y eso también hace uso de Internet (por eso el UnknownHostException). Hasta tal punto que es lo que más bloqueante puede ser (resolver el host, el host está caido, etc).

También debe hacerse fuera del hilo principal.
Responder Con Cita
  #9  
Viejo 29/12/13, 12:53:36
Array

[xs_avatar]
manolazo manolazo no está en línea
Miembro del foro
 
Fecha de registro: jun 2012
Localización: Madrid
Mensajes: 219
Modelo de smartphone: Samsung Galaxy S7 edge
Tu operador: Pepephone
Hola de nuevo.
La linea 72 es efectivamente la creacion del socket: sk = new Socket(ip, puerto);

Pero poniendo la creacion de la conexion

try {
sk = new Socket(ip, puerto);
Log.v(getClass().getCanonicalName(), "Se ha iniciado conexion...");
Log("Conexion con servidor: "+ip+" Puerto: "+puerto);
entrada = new DataInputStream(new BufferedInputStream(sk.getInputStream()));
salida = new DataOutputStream(new BufferedOutputStream(sk.getOutputStream()));

} catch (UnknownHostException e) {
e.printStackTrace();
salidaTxt.append(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
salidaTxt.append(e.getMessage());
}
dentro del Thread tampoco funciona y da el mismo error.

Pero pasa lo siguiente:

Usando un device virtual basado en Android 2.3.3 si que funciona y se establece conexion pero usando un 4.2.2 no funciona. Ni poniendo la conexion dentro ni fuera del Thread.

Que puede haber que funcione en 2.3.3 y no en 4.2.2?? No he probado con demas versiones android.
Alguna idea?

Última edición por manolazo Día 29/12/13 a las 13:00:49.
Responder Con Cita
  #10  
Viejo 29/12/13, 13:02:53
Array

[xs_avatar]
Arasthel Arasthel no está en línea
Cocinero veterano
· Votos compra/venta: (1)
 
Fecha de registro: jun 2009
Localización: Almería
Mensajes: 1,946
Modelo de smartphone: Nexus 5
Tu operador: Amena
La NetworkOnMainThreadException es una excepción que ocurre sólo a partir de Android 3.0 y que sale porque algo que hace uso de red está en el hilo principal, así que algo tiene que haberse quedado fuera del Thread que hace uso del socket o de alguna forma de conexión. Mira el logcat, busca qué línea te dice de tu clase que está fallando (antes era la 72) y ponlo en un hilo aparte.

EDIT: ¿puedes poner el log y también el código tal y como está, a ver si por fin vemos dónde falla esto?

Un saludo.

Última edición por Arasthel Día 29/12/13 a las 13:11:45.
Responder Con Cita
  #11  
Viejo 29/12/13, 13:26:39
Array

[xs_avatar]
neoadn neoadn no está en línea
Usuario muy activo
 
Fecha de registro: abr 2010
Localización: Orense
Mensajes: 632
Modelo de smartphone: Redmi Note 4
Tu operador: Movistar
 Cita: Originalmente Escrito por Arasthel Ver Mensaje
Trabajo asíncrono con red -> hilo aparte. Ponlo en un Thread o en el doInBackground de un AsyncTask y no reventará.

@jtsamper: meter el código en un service sólo para eso es un poco matar moscas a cañonazos, a no ser que tenga que estar funcionando incluso si la app no o que tenga que compartirse en varias activities. Además, si no recuerdo mal, el código de un service sigue ejecutándose en el hilo principal (al menos si está en un proceso aparte).

Un saludo.
A mi me gusta mas un intentService. Ademas se puede comunicar con la app principal bastante fácil y no da tantos problemas al funcionar.

Supongo que para caso habrá lo suyo, pero el service me congelaba una activity y el intentservice no
__________________
Responder Con Cita
  #12  
Viejo 29/12/13, 15:09:42
Array

[xs_avatar]
manolazo manolazo no está en línea
Miembro del foro
 
Fecha de registro: jun 2012
Localización: Madrid
Mensajes: 219
Modelo de smartphone: Samsung Galaxy S7 edge
Tu operador: Pepephone
 Cita: Originalmente Escrito por Arasthel Ver Mensaje
La NetworkOnMainThreadException es una excepción que ocurre sólo a partir de Android 3.0 y que sale porque algo que hace uso de red está en el hilo principal, así que algo tiene que haberse quedado fuera del Thread que hace uso del socket o de alguna forma de conexión. Mira el logcat, busca qué línea te dice de tu clase que está fallando (antes era la 72) y ponlo en un hilo aparte.

EDIT: ¿puedes poner el log y también el código tal y como está, a ver si por fin vemos dónde falla esto?

Un saludo.
Hola, gracias por la aclaración. Ahora ya funciona, no sabia que a partir de la 3.0 tenia que estar todo en un hilo aparte todo lo concerniente a uso de red.

Un a vez puesto todo el un hilo aparte el problema era que dentro dle propio hilo tenia una llamada a Log("Conexion con servidor: "+ip+" Puerto: "+puerto); donde la funcion Log pintaba un textview y eso solo se puede hacer dentro de hilo principal con lo cual usando un handler se soluciona.

Una cuenstion mas.

En caso de querer usar para depurar la aplicación en un dispositivo real, habira que poner la ip de mi conexion a internet en vez del localhost? Un servidor apache?

Un saludo.
Responder Con Cita
  #13  
Viejo 29/12/13, 17:18:56
Array

[xs_avatar]
Arasthel Arasthel no está en línea
Cocinero veterano
· Votos compra/venta: (1)
 
Fecha de registro: jun 2009
Localización: Almería
Mensajes: 1,946
Modelo de smartphone: Nexus 5
Tu operador: Amena
Claro, tendrías que poner la IP del servidor en el que esté, si está en tu propio PC sería la IP externa de tu red. Si quieres que se quede fija, que probablemente será dinámica la que tengas contratada, puedes hacer uso de dyndns o algo parecido para tener una "url" que apunte a tu server.

Un saludo.
Responder Con Cita
  #14  
Viejo 29/12/13, 17:32:17
Array

[xs_avatar]
jtsamper jtsamper no está en línea
Miembro del foro
 
Fecha de registro: abr 2013
Localización: Madrid
Mensajes: 149
Modelo de smartphone: Xperia Arc, Nexus 5
Tu operador: Movistar
 Cita: Originalmente Escrito por Arasthel Ver Mensaje
Trabajo asíncrono con red -> hilo aparte. Ponlo en un Thread o en el doInBackground de un AsyncTask y no reventará.

@jtsamper: meter el código en un service sólo para eso es un poco matar moscas a cañonazos, a no ser que tenga que estar funcionando incluso si la app no o que tenga que compartirse en varias activities. Además, si no recuerdo mal, el código de un service sigue ejecutándose en el hilo principal (al menos si está en un proceso aparte).

Un saludo.
Cierto pero no se porque pensaba en un chat de hay que le dijera de meterlo en un service.
__________________
Controlador de Medicamentos 1.5 (https://play.google.com/store/apps/d...mentcontrolled)
Legislación Basica Española 1.1 (https://play.google.com/store/apps/d...islacionbasica)
Responder Con Cita
  #15  
Viejo 29/12/13, 17:35:17
Array

[xs_avatar]
Arasthel Arasthel no está en línea
Cocinero veterano
· Votos compra/venta: (1)
 
Fecha de registro: jun 2009
Localización: Almería
Mensajes: 1,946
Modelo de smartphone: Nexus 5
Tu operador: Amena
 Cita: Originalmente Escrito por jtsamper Ver Mensaje
Cierto pero no se porque pensaba en un chat de hay que le dijera de meterlo en un service.
Sí, la app parece ser para un chat por los nombres, así que igual el service si es una buena solución. Sólo quería aclarar que si era para una conexión sencilla no hace falta meter un service por medio
Responder Con Cita
  #16  
Viejo 02/01/14, 00:11:39
Array

[xs_avatar]
manolazo manolazo no está en línea
Miembro del foro
 
Fecha de registro: jun 2012
Localización: Madrid
Mensajes: 219
Modelo de smartphone: Samsung Galaxy S7 edge
Tu operador: Pepephone
Hola, muchas gracias por la ayuda.

Hay una cosa que no me queda clara del codigo a ver si me la podeis explicar.

Código:
public class ChatServer {
    
    public ChatServer (int port) throws IOException{        
        ServerSocket server = new ServerSocket(port);
        while (true){
            Socket client = server.accept();
            System.out.println("Aceptado desde :"+client.getInetAddress());
            ChatHandler c = new ChatHandler(client);
            c.start();
        }
    }
    
    public static void main (String args[]) throws IOException {
        new ChatServer(30922);
    }
    
}
Y es por parte del servidor ese bucle while:
No es un bucle en donde se repita la sentencia interna verdad? es decir , si pones un contador o un system.out.prinltn("lo que sea"); no se ejecuta indefinidamente, cuando en este tipo de bucles ha de repetirse indefinidamente hasta que no se cumpla la condicion.

Se supone que ese while es para quedarse indefinidamente a la escucha de aceptar conexiones pero no lo entiendo muy bien.
Responder Con Cita
  #17  
Viejo 02/01/14, 08:41:55
Array

[xs_avatar]
kriogeN kriogeN no está en línea
Colaborador/a
· Votos compra/venta: (1)
 
Fecha de registro: oct 2010
Localización: Murcia
Mensajes: 4,637
Modelo de smartphone: Samsung Galaxy S7 Edge SM-G935F
Tu operador: Vodafone
"server.accept()" es bloqueante, es decir, se quedará ahí hasta que llegue una nueva solicitud de conexión por parte de un cliente.

Es algo muy común cuando se programa un servidor de sockets.
Responder Con Cita
  #18  
Viejo 02/01/14, 11:58:32
Array

[xs_avatar]
manolazo manolazo no está en línea
Miembro del foro
 
Fecha de registro: jun 2012
Localización: Madrid
Mensajes: 219
Modelo de smartphone: Samsung Galaxy S7 edge
Tu operador: Pepephone
OK, no lo sabia.

Gracias.

Edito:

En este caso tambien es bloqueante la lectura de un dataInputStream para la lectura de datos verdad?
Código:
 DataInputStream in = new DataInputStream(s.getInputStream());         
            while (true){                             
                String sMensaje = in.readUTF();
                ventana.mensajeRecibido(sMensaje);
            }
Vale ya veo que si, ya esta claro. Un saludo

Última edición por manolazo Día 02/01/14 a las 14:13:31.
Responder Con Cita
Respuesta

Estás aquí
Regresar   Portal | Indice > Todo sobre Android > Programación y Desarrollo para Android



Hora actual: 00:05:13 (GMT +1)



User Alert System provided by Advanced User Tagging (Lite) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.

Contactar por correo / Contact by mail / 邮件联系 /