客户端在Android上等待来自服务器的消息

时间:2012-04-20 10:46:12

标签: java android multithreading client

我只是想从Java上的服务器和android上的客户端进行连接。我的问题是我创建了一个线程来等待消息在EditText上打印它。我只收到从服务器发送的第一条消息,就像默认消息一样,说“连接成功”现在,当我发送第二条消息时,应用程序才关闭,我必须强行关闭。我确定问题出现在我使用方法leermensajes()的线程上。我不知道该怎么办,现在我是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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

输入流应该在一个循环中,持续监听传入的消息。