2012-04-20 139 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

輸入流應該處於一個不斷偵聽傳入消息的循環中。

相關問題