2012-04-20 157 views
0

我只是试图从Java上的服务器和Android上的客户端进行连接。我的问题是我做了一个线程,等待消息在EditText上打印出来。我只收回从服务器发送的第一条消息,如默认消息,说“连接成功”。现在,当我发送第二条消息时,应用程序就会关闭,我必须强制关闭。我确信问题出在我有leermensajes()方法的线程上。我不知道该怎么做,既然我是Android新手,而且我也没有太多的编程经验。客户端在Android上等待来自服务器的消息

下面是客户端代码

public class ClienteActivity extends Activity { 
      /** Called when the activity is first created. */ 
      private ObjectOutputStream salida; 
      private ObjectInputStream entrada; 
      private String mensaje = ""; 
      private String servidorChat; 
      private int puerto; 
      private Socket cliente; 
      private CheckBox check; 
      private Button boton; 
      private EditText mensajeservidor; 
      private AutoCompleteTextView text; 




     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       setContentView(R.layout.main); 

       // Componentes graficos 
       //Intento dar una accion a un boton 
       boton = (Button) findViewById(R.id.button1); 
       check = (CheckBox) findViewById(R.id.checkBox1); 
       text = (AutoCompleteTextView) findViewById(R.id.textBox); 
       mensajeservidor = (EditText)findViewById(R.id.editText1); 

       servidorChat = "151.57.15.160"; // servidor 
       puerto = 12345; // puerto 

       try { 
        cliente = new Socket(servidorChat , puerto); 
        salida = new ObjectOutputStream(cliente.getOutputStream()); 
        salida.flush(); 
        entrada = new ObjectInputStream(cliente.getInputStream()); 
        //entrada = new ObjectInputStream(cliente.getInputStream()); 
        leermensajes(); 
        //mensaje = (String) entrada.readObject(); 
        //CharSequence cs = mensaje; 
        //mensajeservidor.setText(cs); 

        } 

       catch (EOFException excepcionEOF) { 
        Toast.makeText(ClienteActivity.this,"El cliente termino la conexion",Toast.LENGTH_LONG).show(); 
       } 
       catch (UnknownHostException e) { 
         //Alert que avisa del error 
         Toast.makeText(ClienteActivity.this, R.string.UnkowHost,Toast.LENGTH_LONG).show(); 
         android.util.Log.w("¡¡¡ERROR!!!", e.getMessage()); 
       } catch (IOException e) { 
         Toast.makeText(ClienteActivity.this, R.string.ConectionError,Toast.LENGTH_LONG).show(); 
         android.util.Log.w("¡¡¡ERROR!!!", e.getMessage()); 
       } 


     } 

     protected void onDestroy() { 
       try { 
         salida.close(); 
         cliente.close(); 
       } catch (IOException e) { 
         Toast.makeText(ClienteActivity.this, R.string.errorDesconexion,Toast.LENGTH_LONG).show(); 
         android.util.Log.w("¡¡¡ERROR!!!", e.getMessage()); 
       } 
       super.onDestroy(); 

     } 

     public void onEnviarClick(View button1) { 
       try { 
         if (cliente != null) { 
           salida.writeObject("CLIENTE>>>"+text.getText().toString()); 
           salida.flush(); // vacíar búfer de salida para enviar 
                   // información de encabezado 
         } else 
           Toast.makeText(ClienteActivity.this, R.string.ConectionError,Toast.LENGTH_LONG).show(); 


       } catch (UnknownHostException e) { 
         Toast.makeText(ClienteActivity.this, R.string.UnkowHost,Toast.LENGTH_LONG).show(); 
         android.util.Log.w("¡¡¡ERROR!!!", e.getMessage()); 
       } catch (IOException e) { 
         Toast.makeText(ClienteActivity.this, R.string.ConectionError,Toast.LENGTH_LONG).show(); 
         android.util.Log.w("¡¡¡ERROR!!!", e.getMessage()); 
       } 

     } 

     public void onConectarDesconectar(View checkBox) { 
       if (!check.isChecked()) { 
         boton.setEnabled(false); 
         text.setEnabled(false); 


       } else { 
         boton.setEnabled(true); 
         text.setEnabled(true); 

       } 

     } 

     public void leermensajes(){ 
      new Thread(new Runnable(){ 

       public synchronized void stop(){ 
        cliente = null; 
        salida = null; 
        entrada = null; 

      } 
       public void run() { 

        try { 
         entrada = new ObjectInputStream(cliente.getInputStream()); 
         mensaje = (String) entrada.readObject(); 
         while (true){ 

         CharSequence cs = mensaje; 
         mensajeservidor.setText(cs); 
         } 

         } 

        catch (EOFException excepcionEOF) { 
         Toast.makeText(ClienteActivity.this,"El cliente termino la conexion",Toast.LENGTH_LONG).show(); 
        } 
        catch (UnknownHostException e) { 
          // //Alert que avisa del error 
          Toast.makeText(ClienteActivity.this, R.string.UnkowHost,Toast.LENGTH_LONG).show(); 
          android.util.Log.w("¡¡¡ERROR!!!", e.getMessage()); 
        } catch (IOException e) { 
          Toast.makeText(ClienteActivity.this, R.string.ConectionError,Toast.LENGTH_LONG).show(); 
          android.util.Log.w("¡¡¡ERROR!!!", e.getMessage()); 
        } catch (ClassNotFoundException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
        stop(); 
       } 

      }).start(); 
     } 
    } 

这是服务器代码,但它完美

public Servidor() 
    { 
     super("Servidor"); 

     Container contenedor = getContentPane(); 

     // crear campoIntroducir y registrar componente de escucha 
     campoIntroducir = new JTextField(); 
     campoIntroducir.setEditable(false); 
     campoIntroducir.addActionListener(
     new ActionListener() { 

      // enviar mensaje al cliente 
      public void actionPerformed(ActionEvent evento) 
      { 
       enviarDatos(evento.getActionCommand()); 
       campoIntroducir.setText(""); 
      } 
     } 
    ); 

     contenedor.add(campoIntroducir, BorderLayout.NORTH); 

     // crear areaPantalla 
     areaPantalla = new JTextArea(); 
     contenedor.add(new JScrollPane(areaPantalla), 
     BorderLayout.CENTER); 

     setSize(300, 150); 
     setVisible(true); 

    } // fin del constructor de Servidor 

    // configurar y ejecutar el servidor 
    public void ejecutarServidor() 
    { 
     // configurar servidor para que reciba conexiones; procesar las conexiones 
     try { 

     // Paso 1: crear un objeto ServerSocket. 
     servidor = new ServerSocket(12345, 100); 

     while (true) { 

      try { 
       esperarConexion(); // Paso 2: esperar una conexión. 
       obtenerFlujos();  // Paso 3: obtener flujos de entrada y salida. 
       procesarConexion(); // Paso 4: procesar la conexión. 
      } 

      // procesar excepción EOFException cuando el cliente cierre la conexión 
      catch (EOFException excepcionEOF) { 
       System.err.println("El servidor terminó la conexión"); 
      } 

      finally { 
       cerrarConexion(); // Paso 5: cerrar la conexión. 
       ++contador; 
      } 

     } // fin de instrucción while 

     } // fin del bloque try 

     // procesar problemas con E/S 
     catch (IOException excepcionES) { 
     excepcionES.printStackTrace(); 
     } 

    } // fin del método ejecutarServidor 

    // esperar que la conexión llegue, después mostrar información de la conexión 
    private void esperarConexion() throws IOException 
    { 
     mostrarMensaje("Esperando una conexión\n"); 
     conexion = servidor.accept(); // permitir al servidor aceptar la conexión 
     mostrarMensaje("Conexión " + contador + " recibida de: " + 
     conexion.getInetAddress().getHostName()); 
    } 

    // obtener flujos para enviar y recibir datos 
    private void obtenerFlujos() throws IOException 
    { 
     // establecer flujo de salida para los objetos 
     salida = new ObjectOutputStream(conexion.getOutputStream()); 
     salida.flush(); // vaciar búfer de salida para enviar información de encabezado 

     // establecer flujo de entrada para los objetos 
     entrada = new ObjectInputStream(conexion.getInputStream()); 

     mostrarMensaje("\nSe recibieron los flujos de E/S\n"); 
    } 

    // procesar la conexión con el cliente 
    private void procesarConexion() throws IOException 
    { 
     // enviar mensaje de conexión exitosa al cliente 
     String mensaje = "Conexión exitosa"; 
     enviarDatos(mensaje); 

     // habilitar campoIntroducir para que el usuario del servidor pueda enviar mensajes 
     establecerCampoTextoEditable(true); 

     do { // procesar los mensajes enviados por el cliente 

     // leer el mensaje y mostrarlo en pantalla 
     try { 
      mensaje = (String) entrada.readObject(); 
      mostrarMensaje("\n" + mensaje); 
     } 

     // atrapar problemas que pueden ocurrir al tratar de leer del cliente 
     catch (ClassNotFoundException excepcionClaseNoEncontrada) { 
      mostrarMensaje("\nSe recibió un tipo de objeto desconocido"); 
     } 

     } while (!mensaje.equals("CLIENTE>>> TERMINAR")); 

    } // fin del método procesarConexion 

    // cerrar flujos y socket 
    private void cerrarConexion() 
    { 
     mostrarMensaje("\nFinalizando la conexión\n"); 
     establecerCampoTextoEditable(false); // deshabilitar campoIntroducir 

     try { 
     salida.close(); 
     entrada.close(); 
     conexion.close(); 
     } 
     catch(IOException excepcionES) { 
     excepcionES.printStackTrace(); 
     } 
    } 

    // enviar mensaje al cliente 
    private void enviarDatos(String mensaje) 
    { 
     // enviar objeto al cliente 
     try { 
     salida.writeObject("SERVIDOR>>> " + mensaje); 
     salida.flush(); 
     mostrarMensaje("\nSERVIDOR>>> " + mensaje); 
     } 

     // procesar problemas que pueden ocurrir al enviar el objeto 
     catch (IOException excepcionES) { 
     areaPantalla.append("\nError al escribir objeto"); 
     } 
    } 

    // método utilitario que es llamado desde otros subprocesos para manipular a 
    // areaPantalla en el subproceso despachador de eventos 
    private void mostrarMensaje(final String mensajeAMostrar) 
    { 
     // mostrar mensaje del subproceso de ejecución despachador de eventos 
     SwingUtilities.invokeLater(
     new Runnable() { // clase interna para asegurar que la GUI se actualice apropiadamente 

      public void run() // actualiza areaPantalla 
      { 
       areaPantalla.append(mensajeAMostrar); 
       areaPantalla.setCaretPosition(
        areaPantalla.getText().length()); 
      } 

     } // fin de la clase interna 

    ); // fin de la llamada a SwingUtilities.invokeLater 
    } 

    // método utilitario que es llamado desde otros subprocesos para manipular a 
    // campoIntroducir en el subproceso despachador de eventos 
    private void establecerCampoTextoEditable(final boolean editable) 
    { 
     // mostrar mensaje del subproceso de ejecución despachador de eventos 
     SwingUtilities.invokeLater(
     new Runnable() { // clase interna para asegurar que la GUI se actualice apropiadamente 

      public void run() // establece la capacidad de modificar a campoIntroducir 
      { 
       campoIntroducir.setEditable(editable); 
      } 

     } // fin de la clase interna 

    ); // fin de la llamada a SwingUtilities.invokeLater 
    } 

    public static void main(String args[]) 
    { 
     JFrame.setDefaultLookAndFeelDecorated(true); 
     Servidor aplicacion = new Servidor(); 
     aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     aplicacion.ejecutarServidor(); 
    } 

} // fin de la clase Servidor 
+0

readObject()调用不应该在while循环中吗? – 2012-04-20 10:55:33

回答

0

您为每个邮件打开新流。这不是联网时它应该工作的方式。您应该让流打开,发送和接收内容,然后在完成后关闭它。

+0

你能向我解释我该怎么办?对不起,但我真的不明白你真的想对我说什么。 – Alex 2012-04-21 10:35:09

+0

en la method leerMensajes,no deberia abrir nigun nuevo stream pero utilizar el mismo stream que initializaste connectando al servidor。 Si耐磨材料流,其中包括一个或多个流动通道(con el垃圾回收器)和一个通道交流通道。 Reutilizas tu datainputstream para que sea el mismo durante toda la vida de la communicacion al servidor。 – Snicolas 2012-04-21 10:43:32

0

输入流应该处于一个不断侦听传入消息的循环中。

相关问题