简体   繁体   English

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

[英]Client waits for a message from server on Android

I'm just trying to do a connection from a server on Java and a client on android. 我只是想从Java上的服务器和android上的客户端建立连接。 my problem is that I made a thread for waiting a message to print it on a EditText. 我的问题是我做了一个线程,等待消息将其打印在EditText上。 I only recive the first message that is sent from the server like a default message, saying "connection succesful" Now, when I send a second message the app just close and I have to force the close. 我只能像默认消息一样接收从服务器发送的第一条消息,说“连接成功”。现在,当我发送第二条消息时,应用程序刚刚关闭,我不得不强制关闭。 I'm sure that the problem is on the thread that is where I have the method leermensajes(). 我确定问题出在具有方法leermensajes()的线程上。 I don't know what to do, now that I'm newbie on Android and also I don't have much experience programming. 我不知道该怎么办,因为我是Android的新手,而且我也没有太多编程经验。

Here is the client code 这是客户代码

 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();
        }
   } 

this is the Server code but it works perfectly 这是服务器代码,但效果很好

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

You open new streams for each message. 您为每个消息打开新的流。 That's not the way it should work when doing networking. 那不是进行网络连接时的工作方式。 You should let the stream open, send and receive stuff, then, when done, close it. 您应该让流打开,发送和接收内容,然后在完成后将其关闭。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM