2013-02-11 13 views
8

Sto costruendo un semplice server Bluetooth Java per il mio computer utilizzando l'API Bluecove. Sto creando anche un'app client lato Android, ma il problema sembra derivare dall'app lato server.Mantenere attiva la connessione Bluetooth Java

Sono sicuro che qualcuno ha già inviato una risposta da qualche parte e ho provato diverse soluzioni rigorosamente negli ultimi giorni e ho esaminato tutti i possibili forum, ma non riesco a mantenere viva la connessione sul thread del socket.

Posso scambiare un messaggio attraverso dopo aver stabilito una connessione da Android a computer e viceversa da computer ad Android ma immediatamente dopo lo scambio dei byte, lo stack Bluecove si spegne e chiude la connessione socket anche quando non lo faccio ditelo esplicitamente a connection.close().

Ho provato a utilizzare un ciclo while (alcune istruzioni è vero) per mantenere attiva la connessione e non spegne più il socket dopo aver ricevuto il primo messaggio ma non può ricevere alcun messaggio successivo che invio dal mio smartphone al mio computer. Mentre è essenzialmente vivo, non può ricevere nuovi messaggi quando provo a inviarli dallo smartphone. Non so perché.

Mi dispiace, questa è la mia prima pubblicazione e non sono sicuro del motivo per cui la prima parte del codice non viene visualizzata correttamente nella pagina.

Codice di effettuare il collegamento:

public BluetoothServer() 
{ 
    try 
    { 
     service = (StreamConnectionNotifier) 
      Connector.open("btspp://localhost:" + new UUID(0x1101).toString() + 
           ";name=SampleServer"); 

      System.out.println("open connection"); 



      while(runState == true){ 

       connection = (StreamConnection) service.acceptAndOpen(); 

//send a greeting across to android 
        outputStream = connection.openOutputStream(); 
        String greeting = "JSR-82 RFCOMM server says hello"; 
        outputStream.write(greeting.getBytes()); 

//run thread that listens for incoming bytes through socket connection 
       Thread t = new Thread(new ConnectedThread(connection)); 
       t.start(); 

      } 

    } catch(IOException e) {} 
} 

CODICE FILETTO per l'ascolto di INCOMING DATI

public void run() 
{ 
    try 
    {  
      //open input stream to listen to data 
      inputStream = connection.openInputStream();    

      byte buffer[] = new byte[1024]; 
      int bytes_read = inputStream.read(buffer); 

      String received = new String(buffer, 0, bytes_read); 
      System.out.println("received: " + received); 

    } 
     catch(IOException e){} 
} 
+0

Non è possibile inviare più di un messaggio dal client al server, ma è possibile inviare più messaggi dal server al client? Quale loop chiama il tuo metodo run()? Potete fornire anche questo codice che chiama run()? –

+0

In passato ho un problema molto simile. Ma nel mio caso, la connessione non è stata chiusa, solo la velocità dell'IO stava rallentando (sul lato Android). Dopo il debug, abbiamo scoperto, dopo un certo periodo di inattività, che si verifica sul lato Android dopo un timeout specifico (Android attiva la modalità di sicurezza dell'alimentazione) e questo timeout non può essere modificato. Per mantenere attiva la connessione, abbiamo inviato periodicamente pacchetti vuoti (un byte). Spero che ti sarà d'aiuto. – Eugene

+0

Non utilizzare solo blocchi try/catch vuoti. Registra l'eccezione quando viene lanciata, ti aiuterà a ottenere una vera ragione. Altrimenti stai indovinando. – Don

risposta

0

Purtroppo non posso provare il codice sulla mia macchina in tempo reale, ma penso che ho visto il tuo errore : nella tua esecuzione() - Metodo che leggi dallo stream di input, stampalo sulla console e poi è finito. Dopo l'ultima riga

 System.out.println("received: " + received); 

il tuo run() - Il metodo è finito e il thread è scartato dal runtime. Dovresti mettere la ricezione tra un ciclo while (vero) o while (in esecuzione).

Ho modificato il tuo codice ed eccolo, tuttavia tieni presente ciò che ho detto prima: non ho potuto testarlo, quindi è assolutamente non testato!

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

import javax.bluetooth.UUID; 
import javax.microedition.io.Connector; 
import javax.microedition.io.StreamConnection; 
import javax.microedition.io.StreamConnectionNotifier; 


public class BluetoothServer { 

    private boolean runState = true; 

    public BluetoothServer(){ 

     try { 
      StreamConnectionNotifier service = (StreamConnectionNotifier) Connector.open("btspp://localhost:" + new UUID(0x1101).toString() + ";name=SampleServer"); 
      System.out.println("open connection"); 

      while(runState == true){ 
       StreamConnection connection = (StreamConnection) service.acceptAndOpen(); 
       new Listener(connection).start(); 
      } 

     } catch(IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private class Listener extends Thread{ 

     private OutputStream os; 
     private InputStream is; 

     public Listener(StreamConnection connection){ 
      try { 
       this.os = connection.openOutputStream(); 
       os.flush(); 
       this.is = connection.openInputStream(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

     public void run(){ 
      StringBuilder builder; 
      try{ 
       String greeting = "JSR-82 RFCOMM server says hello"; 
       os.write(greeting.getBytes()); 

       while(true){ 
        builder = new StringBuilder(); 
        int tmp = 0; 
        while((tmp = is.read()) != -1){ 
         builder.append((char) tmp); 
        } 
        System.out.println("received: " + builder.toString()); 
       } 
      } 
      catch(IOException e){ 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

Ecco alcuni punti generali e pensieri su mio e il tuo codice:

  • Come si può vedere, nel thread principale che accettano solo una nuova connessione. Non appena un client si connette, fornisco l'oggetto connessione al thread. Quindi inizia a comunicare con il client
  • In Java, normalmente mettiamo parentesi di apertura sulla stessa riga dell'istruzione che la richiede, ma questo è solo un dettaglio e non un must.
  • ALLWAYS fa qualcosa con le eccezioni o non le cattura. Quindi il minimo è un printStacktrace() o per dichiarare il tuo metodo con "getta xException" ma non catturarlo e ignorarlo.

Per la prossima volta che pubblichi qualcosa qui, ti consiglio di includere tutte le tue istruzioni di importazione ecc., Può aiutare le persone che stanno cercando di aiutarti. (a volte, un'importazione può essere la causa di tutti i problemi, ad esempio quando qualcuno ha importato java.awt.List invece di java.util.Elenco)

Spero di averti aiutato!

Problemi correlati